您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Java Swing編程的特殊容器是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
Swing還提供我們許多特殊容器方便我們編程,JSplitPane(分割面板),JTabbedPane(多選項卡),JLayeredPane(層容器,允許組件互相重疊),講兩個復雜的容器JDesktopPane和JInternalFrame這些多是為了實現MDI(多文檔界面),這些容器不是三言兩語能說清楚的,所以我將以舉例的方式(其中多是書中的例子,舉的都不錯,自己一個一個寫可吃不消),如還有不懂的,請多查閱API文檔。
eg:JSplitPane(分割面板)
public class TestSplitPane { Book[] books = new Book[]{ new Book("Struts2權威指南" , new ImageIcon("ico/struts2.jpg") , "全面介紹Struts2的各方/n面知識"), new Book("輕量級J2EE企業應用實戰" , new ImageIcon("ico/j2ee.jpg") , "介紹Struts、Spring和/nHibernate整合開發的知識"), new Book("基于J2EE的Ajax寶典" , new ImageIcon("ico/ajax.jpg") , "全面介紹J2EE平臺上Ajax/n開發的各方面知識") }; JFrame jf = new JFrame("測試JSplitPane"); JList bookList = new JList(books); JLabel bookCover = new JLabel(); JTextArea bookDesc = new JTextArea(); public void init() { //為三個組件設置***大小 bookList.setPreferredSize(new Dimension(150, 300)); bookCover.setPreferredSize(new Dimension(300, 150)); bookDesc.setPreferredSize(new Dimension(300, 150)); //為下拉列表添加事件監聽器 bookList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent event) { Book book = (Book)bookList.getSelectedValue(); bookCover.setIcon(book.getIco()); bookDesc.setText(book.getDesc()); } }); //創建一個垂直的分割面板, //將bookCover放在上面,將bookDesc放在下面 , 支持連續布局 JSplitPane left = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true , bookCover, new JScrollPane(bookDesc)); //打開“一觸即展”的特性 left.setOneTouchExpandable(true); //下面代碼設置分割條的大小。 //left.setDividerSize(50); //設置該分割面板根據所包含組件的***大小來調整布局 left.resetToPreferredSizes(); //創建一個水平的分割面板 //將left組件放在左邊,將bookList組件放在右邊 JSplitPane content = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, bookList); jf.add(content); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); } public static void main(String[] args) { new TestSplitPane().init(); } } class Book { private String name; private Icon ico; private String desc; public Book(){} public Book(String name , Icon ico , String desc) { this.name = name; this.ico = ico; this.desc = desc; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setIco(Icon ico) { this.ico = ico; } public Icon getIco() { return this.ico; } public void setDesc(String desc) { this.desc = desc; } public String getDesc() { return this.desc; } public String toString() { return name; } }
eg:JTabbedPane(多選項卡)
public class TestJTabbedPane { JFrame jf = new JFrame("測試Tab頁面"); //創建一個Tab頁面的標簽放在左邊,采用換行布局策略的JTabbedPane JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.LEFT , JTabbedPane.WRAP_TAB_LAYOUT); ImageIcon icon = new ImageIcon("ico/close.gif"); String[] layouts = {"換行布局" , "滾動條布局"}; String[] positions = {"左邊" , "頂部" , "右邊" , "底部"}; Map<String , String> books = new LinkedHashMap<String , String>(); public void init() { books.put("ROR敏捷開發***實踐" , "ror.jpg"); books.put("Struts2權威指南" , "struts2.jpg"); books.put("基于J2EE的Ajax寶典" , "ajax.jpg"); books.put("輕量級J2EE企業應用實戰" , "j2ee.jpg"); books.put("Spring2.0寶典" , "spring.jpg"); String tip = "可看到本書的封面照片"; //向JTabbedPane中添加5個Tab頁面,指定了標題、圖標和提示,但該Tab頁面的組件為null for (String bookName : books.keySet()) { tabbedPane.addTab(bookName, icon, null , tip); } jf.add(tabbedPane, BorderLayout.CENTER); //為JTabbedPane添加事件監聽器 tabbedPane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { //如果被選擇的組件依然是空 if (tabbedPane.getSelectedComponent() == null) { //獲取所選Tab頁 int n = tabbedPane.getSelectedIndex(); //為指定標前頁加載內容 loadTab(n); } } }); //系統默認選擇***頁,加載***頁內容 loadTab(0); tabbedPane.setPreferredSize(new Dimension(500 , 300)); //增加控制標簽布局、標簽位置的單選按鈕 JPanel buttonPanel = new JPanel(); ChangeAction action = new ChangeAction(); buttonPanel.add(new ButtonPanel(action , "選擇標簽布局策略" ,layouts)); buttonPanel.add (new ButtonPanel(action , "選擇標簽位置" ,positions)); jf.add(buttonPanel, BorderLayout.SOUTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); } //為指定標簽頁加載內容 private void loadTab(int n) { String title = tabbedPane.getTitleAt(n); //根據標簽頁的標題獲取對應圖書封面 ImageIcon bookImage = new ImageIcon("ico/" + books.get(title)); tabbedPane.setComponentAt(n, new JLabel(bookImage)); //改變標簽頁的圖標 tabbedPane.setIconAt(n, new ImageIcon("ico/open.gif")); } //定義改變標簽頁的布局策略,放置位置的監聽器 class ChangeAction implements ActionListener { public void actionPerformed(ActionEvent event) { JRadioButton source = (JRadioButton)event.getSource(); String selection = source.getActionCommand(); if (selection.equals(layouts[0])) { tabbedPane.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT); } else if (selection.equals(layouts[1])) { tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); } else if (selection.equals(positions[0])) { tabbedPane.setTabPlacement(JTabbedPane.LEFT); } else if (selection.equals(positions[1])) { tabbedPane.setTabPlacement(JTabbedPane.TOP); } else if (selection.equals(positions[2])) { tabbedPane.setTabPlacement(JTabbedPane.RIGHT); } else if (selection.equals(positions[3])) { tabbedPane.setTabPlacement(JTabbedPane.BOTTOM); } } } public static void main(String[] args) { new TestJTabbedPane().init(); } } //定義一個JPanel類擴展類,該類的對象包含多個縱向排列的JRadioButton控件 //且Panel擴展類可以指定一個字符串作為TitledBorder class ButtonPanel extends JPanel { private ButtonGroup group; public ButtonPanel(TestJTabbedPane.ChangeAction action , String title, String[] labels) { setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title)); setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); group = new ButtonGroup(); for (int i = 0; labels!= null && i < labels.length; i++) { JRadioButton b = new JRadioButton(labels[i]); b.setActionCommand(labels[i]); add(b); //添加事件監聽器 b.addActionListener(action); group.add(b); b.setSelected(i == 0); } } }
eg:JLayeredPane(層容器,允許組件互相重疊)
public class TestJLayeredPane { JFrame jf = new JFrame("測試JLayeredPane"); JLayeredPane layeredPane = new JLayeredPane(); public void init() { //向layeredPane中添加3個組件 layeredPane.add(new ContentPanel(10 , 20 , "Struts2權威指南" , "ico/struts2.jpg"), JLayeredPane.MODAL_LAYER); layeredPane.add(new ContentPanel(100 , 60 , "RoR敏捷開發***實踐", "ico/ror.jpg"), JLayeredPane.DEFAULT_LAYER); layeredPane.add(new ContentPanel(190 , 100 , "輕量級J2EE企業應用實戰", "ico/j2ee.jpg"), 4); layeredPane.setPreferredSize(new Dimension(400, 300)); layeredPane.setVisible(true); jf.add(layeredPane); jf.pack(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } public static void main(String[] args) { new TestJLayeredPane().init(); } } //擴展了JPanel類,可以直接創建一個放在指定位置, //且有指定標題、放置指定圖標的JPanel對象 class ContentPanel extends JPanel { public ContentPanel(int xPos , int yPos , String title , String ico) { setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title)); JLabel label = new JLabel(new ImageIcon(ico)); add(label); setBounds(xPos , yPos , 160, 200); } }
以上3例子由于都是廣告,我就不貼給大家了,沒圖片不影響程序的效果。
***是JDesktopPane和JInternalFrame來實現MDI
public class TestInternalFrame { final int DESKTOP_WIDTH = 480; final int DESKTOP_HEIGHT = 360; final int FRAME_DISTANCE = 30; JFrame jf = new JFrame("MDI界面"); //定義一個虛擬桌面 private MyJDesktopPane desktop = new MyJDesktopPane(); //保存下一個內部窗口的座標點 private int nextFrameX; private int nextFrameY; //定義內部窗口為虛擬桌面的1/2大小 private int width = DESKTOP_WIDTH / 2; private int height = DESKTOP_HEIGHT / 2; //為主窗口定義2個菜單 JMenu fileMenu = new JMenu("文件"); JMenu windowMenu = new JMenu("窗口"); //定義newAction用于創建菜單和工具按鈕 Action newAction = new AbstractAction("新建", new ImageIcon("ico/new.png")) { public void actionPerformed(ActionEvent event) { //創建內部窗口 final JInternalFrame iframe = new JInternalFrame("新文檔", true, // 可改變大小 true, // 可關閉 true, // 可***化 true); // 可最小化 iframe.add(new JScrollPane(new JTextArea(8, 40))); //將內部窗口添加到虛擬桌面中 desktop.add(iframe); //設置內部窗口的原始位置(內部窗口默認大小是0X0,放在0,0位置) iframe.reshape(nextFrameX, nextFrameY, width, height); //使該窗口可見,并嘗試選中它 iframe.show(); //計算下一個內部窗口的位置 nextFrameX += FRAME_DISTANCE; nextFrameY += FRAME_DISTANCE; if (nextFrameX + width > desktop.getWidth()) nextFrameX = 0; if (nextFrameY + height > desktop.getHeight()) nextFrameY = 0; } }; //定義exitAction用于創建菜單和工具按鈕 Action exitAction = new AbstractAction("退出", new ImageIcon("ico/exit.png")) { public void actionPerformed(ActionEvent event) { System.exit(0); } }; public void init() { //為窗口安裝菜單條和工具條 JMenuBar menuBar = new JMenuBar(); JToolBar toolBar = new JToolBar(); jf.setJMenuBar(menuBar); menuBar.add(fileMenu); fileMenu.add(newAction); fileMenu.add(exitAction); toolBar.add(newAction); toolBar.add(exitAction); menuBar.add(windowMenu); JMenuItem nextItem = new JMenuItem("下一個"); nextItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { desktop.selectNextWindow(); } }); windowMenu.add(nextItem); JMenuItem cascadeItem = new JMenuItem("級聯"); cascadeItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //級聯顯示窗口,內部窗口的大小是外部窗口的0.75 desktop.cascadeWindows(FRAME_DISTANCE , 0.75); } }); windowMenu.add(cascadeItem); JMenuItem tileItem = new JMenuItem("平鋪"); tileItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //平鋪顯示所有內部窗口 desktop.tileWindows(); } }); windowMenu.add(tileItem); final JCheckBoxMenuItem dragOutlineItem = new JCheckBoxMenuItem("僅顯示拖動窗口的輪廓"); dragOutlineItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //根據該菜單項是否選擇來決定采用哪種拖動模式 desktop.setDragMode(dragOutlineItem.isSelected() ? JDesktopPane.OUTLINE_DRAG_MODE : JDesktopPane.LIVE_DRAG_MODE); } }); windowMenu.add(dragOutlineItem); desktop.setPreferredSize(new Dimension(480, 360)); //將虛擬桌面添加到***JFrame容器中 jf.add(desktop); jf.add(toolBar , BorderLayout.NORTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); } public static void main(String[] args) { new TestInternalFrame().init(); } } class MyJDesktopPane extends JDesktopPane { //將所有窗口以級聯方式顯示, //其中offset是兩個窗口的位移距離,scale是內部窗口與JDesktopPane的大小比例 public void cascadeWindows(int offset , double scale) { //定義級聯顯示窗口時內部窗口的大小 int width = (int)(getWidth() * scale); int height = (int)(getHeight() * scale); //用于保存級聯窗口時每個窗口的位置 int x = 0; int y = 0; for (JInternalFrame frame : getAllFrames()) { try { //取消內部窗口的***化,最小化 frame.setMaximum(false); frame.setIcon(false); //把窗口重新放置在指定位置 frame.reshape(x, y, width, height); x += offset; y += offset; //如果到了虛擬桌面邊界 if (x + width > getWidth()) x = 0; if (y + height > getHeight()) y = 0; } catch (PropertyVetoException e) {} } } //將所有窗口以平鋪方式顯示 public void tileWindows() { //統計所有窗口 int frameCount = 0; for (JInternalFrame frame : getAllFrames()) { frameCount++; } //計算需要多少行、多少列才可以平鋪所有窗口 int rows = (int) Math.sqrt(frameCount); int cols = frameCount / rows; //需要額外增加到其他列中的窗口 int extra = frameCount % rows; //計算平鋪時內部窗口的大小 int width = getWidth() / cols; int height = getHeight() / rows; //用于保存平鋪窗口時每個窗口在橫向、縱向上的索引 int x = 0; int y = 0; for (JInternalFrame frame : getAllFrames()) { try { //取消內部窗口的***化,最小化 frame.setMaximum(false); frame.setIcon(false); //將窗口放在指定位置 frame.reshape(x * width, y * height, width, height); y++; //每排完一列窗口 if (y == rows) { //開始排放下一列窗口 y = 0; x++; //如果額外多出的窗口與剩下的列數相等,則后面所有列都需要多排列一個窗口 if (extra == cols - x) { rows++; height = getHeight() / rows; } } } catch (PropertyVetoException e) {} } } //選中下一個非圖標窗口 public void selectNextWindow() { JInternalFrame[] frames = getAllFrames(); for (int i = 0; i < frames.length; i++) { if (frames[i].isSelected()) { // 找出下一個非最小化的窗口,嘗試選中它, //如果選中失敗,則繼續嘗試選中下一個窗口 int next = (i + 1) % frames.length; while (next != i) { //如果該窗口不是處于最小化狀態 if (!frames[next].isIcon()) { try { frames[next].setSelected(true); frames[next].toFront(); frames[i].toBack(); return; } catch (PropertyVetoException e) {} } next = (next + 1) % frames.length; } } } } }
大家注意看繼承JDesktopPane的類MyJDesktopPane
其中的3個方法非常有用,這是對窗口控制的基本方法(級聯,平鋪,選下個窗口),大家可以保留下來,以備后用。
看完上述內容,你們對Java Swing編程的特殊容器是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。