Swing组件setSize()/ setBounds()问题

时间:2012-02-02 18:01:53

标签: java swing resize jpanel

内容


  1. 概述
  2. 示例代码
  3. 问题的屏幕截图

  4. 1。问题概述


    所以我正在编写一个用于我正在开发的复杂程序的GUI,我厌倦了在调整窗口大小时尝试正确扩展组件。

    起初我在jframe中使用了几个布局,并且每个jpanel都尝试正确放置组件并适当地缩放它们。当然,我厌倦了他们,我开始尝试缩放并动态设置组件的x,y位置(它更容易:D)。

    基本上我试图将屏幕划分为左边距(JSplitPane),中心(JTabbedPane)和右边距(JSplitPane)三个部分。我不认为内部组件在这一点上很重要。 主要问题是正确的JSplitPane在整个窗口上进行缩放,尽管我使用setBounds()将x,y放在右边,并将大小设置为总宽度的21%。它似乎与其他小组互动很奇怪。


    2。示例代码


    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSplitPane;
    import javax.swing.JTabbedPane;
    
    import java.awt.event.ComponentEvent;
    import java.awt.event.ComponentListener;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowListener;
    import java.awt.Dimension;
    
    @SuppressWarnings("deprecation")
    public class test extends JFrame implements WindowListener {
    
    /* Constants =========================================================================*/
        private         final   double      LEFT_SIZE           =   .21;
        private         final   double      CENTER_SIZE         =   .58;
        private         final   double      RIGHT_SIZE          =   .21;
        private         final   int         TOP_PADDING         =   50;
        private         final   int         LEFT_PADDING        =   4;
        private         final   int         RIGHT_PADDING       =   4;
        private         final   int         BOTTOM_PADDING      =   4;
        private         final   int         MIN_WIDTH           =   640;
        private         final   int         MIN_HEIGHT          =   480;
    
        public  static  final   String      INIT_TITLE          =   "TestFrame v0.01";
    /* End Constants =====================================================================*/
    
    /* Instance Variables ================================================================*/
        private                 int         contentWidth;
        private                 int         contentHeight;
    /* End Instance Variables ============================================================*/
    
    /* Objects ===========================================================================*/        
        public  static  test        window;     
    
        /* Begin Frame Design =========================================================== */
            private         JSplitPane      left;
            private         JButton           button1;  private     JButton     button2;            
            private         JTabbedPane     center;
            private         JPanel            panel1;       private     JPanel      panel2;         
            private         JSplitPane      right;
            private         JButton           button3;  private     JButton     button4;
        /* End Frame Design ============================================================= */
    
    /* End Objects ====================================================================== */
    
    /** Initializes and Places all GUI elements **/
    public test ( String windowName ) {
        super(windowName);              //call parent constructor
        this.addWindowListener(this);   //adds window event functionality such as close
    
        this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH); //Starts program maximized
        this.setMinimumSize(new Dimension(MIN_WIDTH,MIN_HEIGHT));
        this.setVisible(true);
        this.setMaximumSize(this.getSize());        
    
        /* Begin Init JFrame this ------------------------------------------------------------ */       
                button1 = new JButton("button1");               
                button2 = new JButton("button2");               
            left = new JSplitPane(JSplitPane.VERTICAL_SPLIT, button1, button2);
            left.setResizeWeight(1);
    
                button3 = new JButton("button3");               
                button4 = new JButton("button4");               
            right = new JSplitPane(JSplitPane.VERTICAL_SPLIT, button3, button4);
            right.setResizeWeight(.25);
    
                panel1 = new JPanel();              
                panel2 = new JPanel();              
            center = new JTabbedPane();
            center.addTab("Panel1", panel1);
            center.addTab("Panel2", panel2);
    
            this.add(left);
            this.add(center);
            this.add(right);
    
            this.addComponentListener(new ComponentListener() {
                @Override
                public void componentResized    (ComponentEvent e) {
                    window.contentWidth = window.getWidth() - window.LEFT_PADDING - window.RIGHT_PADDING;
                    window.contentHeight = window.getHeight() - window.TOP_PADDING - window.BOTTOM_PADDING;
    
                    window.left.setBounds               (   0,                                                  0,  (int)(window.contentWidth * window.LEFT_SIZE),      window.contentHeight);
                    window.center.setBounds             (   window.left.getWidth(),                             0,  (int)(window.contentWidth * window.CENTER_SIZE),    window.contentHeight);
                    window.panel1.setBounds             (   0,                                                  0,  (int)(window.contentWidth * window.CENTER_SIZE),    window.contentHeight);
                    window.panel2.setBounds             (   0,                                                  0,  (int)(window.contentWidth * window.CENTER_SIZE),    window.contentHeight);
                    window.right.setBounds              (   window.left.getWidth() + window.center.getWidth(),  0,  (int)(window.contentWidth * window.RIGHT_SIZE),     window.contentHeight);
                 }
                public void componentHidden     (ComponentEvent e) {}
                public void componentMoved      (ComponentEvent e) {}
                public void componentShown      (ComponentEvent e) {}    
    
            });
            /* End Init JFrame this -------------------------------------------------------------- */
    }
    
    // window event abstracts
    @Override
    public void windowClosing       (WindowEvent event)     { window.dispose(); System.exit(0); } 
    public void windowClosed        (WindowEvent event)     {}
    public void windowDeiconified   (WindowEvent event)     {} 
    public void windowIconified     (WindowEvent event)     {} 
    public void windowActivated     (WindowEvent event)     {} 
    public void windowDeactivated   (WindowEvent event)     {} 
    public void windowOpened        (WindowEvent event)     {}
    
    public static void main(String[] args){     
        window = new test(INIT_TITLE); 
        window.setVisible(true);
    }
    }
    

    3。屏幕截图


    Screenshot1 Screenshot2

1 个答案:

答案 0 :(得分:3)

  

我认为内部组件在这一点上并不重要。

正如Should I avoid the use of set[Preferred|Maximum|Minimum]Size methods in Java Swing?中所讨论的那样,事实并非如此。正确使用布局依赖组件的首选大小。该尺寸是根据内容仔细计算的。如你的例子所示,第二次猜测注定要失败。

相反,添加组件和pack()框架。在下面的示例中,中心面板返回任意结果,以显示pack()的工作方式。

附录:@mKorbel提出的另外两点:

  • 应在event dispatch thread构建和操作Swing GUI对象。

  • 另请参阅此example,了解如何在setDividerLocation()中使用invokeLater()

enter image description here

import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import java.awt.Dimension;
import java.awt.EventQueue;

public class Test extends JFrame {

    public static final String INIT_TITLE = "TestFrame v0.02";
    public static Test window;
    private JSplitPane left;
    private JTabbedPane center;
    private JSplitPane right;

    public Test(String windowName) {
        super(windowName);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        left = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
            new JButton("button1"), new JButton("button2"));
        left.setResizeWeight(0.5);

        right = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
            new JButton("button3"), new JButton("button4"));
        right.setResizeWeight(0.5);

        center = new JTabbedPane();
        center.addTab("Panel1", new MyPanel());
        center.addTab("Panel2", new MyPanel());

        this.add(left, BorderLayout.WEST);
        this.add(center, BorderLayout.CENTER);
        this.add(right, BorderLayout.EAST);

        this.pack();
        this.setLocationByPlatform(true);
        this.setVisible(true);
    }

    private static class MyPanel extends JPanel {

        private Dimension d = new Dimension(320, 240);

        @Override
        public Dimension getPreferredSize() {
            return d;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                window = new Test(INIT_TITLE);
                window.setVisible(true);
            }
        });
    }
}