今天就跟大家聊聊有关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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。