Swing组件setSize()/setBounds()问题 [英] Swing component setSize()/setBounds() issue

查看:98
本文介绍了Swing组件setSize()/setBounds()问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


1.问题概述


因此,我正在为正在开发的复杂程序编写GUI,并且厌倦了在调整窗口大小时试图使组件正确缩放的方法.


1. Overview of problem


So I'm writing a GUI for a complicated program I'm developing, and I get tired of trying to get components to scale correctly when the window is resized.

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

At first I was using several layouts inside the jframe, and each jpanel to try and place the components correctly and scale them appropriately. Naturally, I got fed up with them, and I started trying to scale and set the x,y positions of the components dynamically (it's so much easier :D).

基本上,我正在尝试将屏幕分为左边界(JSplitPane),中心(JTabbedPane)和右边界(JSplitPane)三个部分.我认为目前内部组件并不重要. 主要问题是,尽管我使用setBounds()将x,y放在右侧并将大小设置为总宽度的21%,但右侧的JSplitPane会在整个窗口上缩放.看来与其他面板的互动很奇怪.

Basically I'm trying to divide the screen into three sections left margin (JSplitPane), center (JTabbedPane), and right margin (JSplitPane). I don't think the internal components matter at this point. The main problem is the right JSplitPane scales over the whole window despite my using setBounds() to place the x,y over on the right and set the size to 21% of the total width. It seems to interact weird with the other panels.

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.截图



3. Screenshots


推荐答案

我不认为内部组件很重要.

I don't think the internal components matter at this point.

中所述,我应该避免在Java Swing中使用set [Preferred | Maximum | Minimum] Size方法吗? ,事实真相无可厚非.正确使用布局 取决于组件的首选大小.该大小是根据内容仔细计算的.如您的示例所示,第二个猜测注定要失败.

As discussed in Should I avoid the use of set[Preferred|Maximum|Minimum]Size methods in Java Swing?, nothing could be further from the truth. Correct use of layouts relies on a component's preferred size. That size is carefully calculated based on the contents. Second guessing, as shown in your example, is doomed to fail.

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

Instead, add components and pack() the frame. In the example below, the center panel returns an arbitrary result to show how pack() does its work.

附录:@mKorbel有益地引用了另外两个要点:

Addendum: Two additional points helpfully adduced by @mKorbel:

  • 仅在另请参见以下示例,该示例显示了如何在invokeLater()中使用setDividerLocation().

    See also this example that shows how to use setDividerLocation() in invokeLater().

    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);
                }
            });
        }
    }
    

    这篇关于Swing组件setSize()/setBounds()问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆