调整框架上的组件大小调整Java大小

调整框架上的组件大小调整Java大小,java,swing,user-interface,resize,gridbaglayout,Java,Swing,User Interface,Resize,Gridbaglayout,在调整GUI的大小时,尝试调整GUI中的组件时遇到了一些问题。现在,当我调整GUI的大小时,组件的大小不会改变,而是保持我设置的静态大小。当我调整GUI的大小超过显示它们所需的最小大小时,它们将不再显示。我希望它们在调整GUI大小时调整大小并保持纵横比 以下是我为GUI编写的代码: import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; impor

在调整GUI的大小时,尝试调整GUI中的组件时遇到了一些问题。现在,当我调整GUI的大小时,组件的大小不会改变,而是保持我设置的静态大小。当我调整GUI的大小超过显示它们所需的最小大小时,它们将不再显示。我希望它们在调整GUI大小时调整大小并保持纵横比

以下是我为GUI编写的代码:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.*;
import java.net.*;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class DraftGUI implements MouseListener {

private JPanel jpPack;
private JPanel jpCards;
private JPanel jpInfo;
private JPanel jpChat;
private TextField tf;
private StyledDocument doc;
private JTextPane tp;
private JScrollPane sp;

public void mousePressed(MouseEvent e) {
}

public void mouseReleased(MouseEvent e) {
}

public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

public void mouseClicked(MouseEvent e) {
    e.getComponent().setVisible(false);
}

private Client client;


public GUI(Client client) throws IOException {

    JFrame frame = new JFrame("Draft");

    //set the size to fullscreen to start
    frame.setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);

    //set the content pane, we'll add everything to it and then add it to the frame
    JPanel contentPane = new JPanel();
    contentPane.setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
    contentPane.setLayout(new GridBagLayout());

    //creates some panels with some default values for now
    JPanel jpCards = new JPanel(new BorderLayout());
    jpCards.setOpaque(true); //ensures it paints every pixel
    jpCards.setBackground(Color.BLUE);

    JPanel jpInfo = new JPanel();
    jpInfo.setOpaque(true);
    jpInfo.setBackground(Color.GREEN);

    JPanel jpPack = new JPanel(new GridBagLayout());
    jpPack.setOpaque(true);
    jpPack.setBackground(Color.RED);

    //grab some info to make the JTextPane and make it scroll
    this.client = client;
    tf = new TextField();
    doc = new DefaultStyledDocument();
    tp = new JTextPane(doc);
    tp.setEditable(false);
    tf.addActionListener(this.client);
    sp = new JScrollPane(tp);

    //adding the quantities to the chat panel
    JPanel jpChat = new JPanel();
    jpChat.setLayout(new BorderLayout());
    jpChat.add("North", tf);
    jpChat.add("Center", sp);

    //a new GridBagConstraints used to set the properties/location of the panels
    GridBagConstraints c = new GridBagConstraints(); 

    //adding some panels to the content pane
    //set it to start from the top left of the quadrant if it's too small
    c.anchor = GridBagConstraints.FIRST_LINE_START; 
    c.fill = GridBagConstraints.BOTH; //set it to fill both vertically and horizontally
    c.gridx = 0; //set it to quadrant x=0 and
    c.gridy = 0; //set it to quadrant y=0
    c.weightx = 0.7;
    c.weighty = 0.3;
    contentPane.add(jpCards, c);

    c.gridx = 1;
    c.gridy = 0;
    c.weightx = 0.3;
    c.weighty = 0.3;
    contentPane.add(jpInfo, c);

    c.gridx = 0;
    c.gridy = 1;
    c.weightx = 0.7;
    c.weighty = 0.7;
    contentPane.add(jpPack, c);

    c.gridx = 1;
    c.gridy = 1;
    c.weightx = 0.3;
    c.weighty = 0.7;
    contentPane.add(jpChat, c);

    //set some necessary values 
    frame.setContentPane(contentPane);
    frame.setLocationByPlatform(true);
    frame.setVisible(true);

    //This code works for adding an Image
    //need to learn how to specify a path not dependent on the specific users's machine
    //this is not a high priority for now though
    GridBagConstraints d = new GridBagConstraints();
    d.gridx = 0;
    d.gridy = 0;

    ImageLabel imageLabel1 = new ImageLabel("path-to-file");

    imageLabel1.setPreferredSize(new Dimension(223, 310));
    jpPack.add(imageLabel1, d);

    ImageLabel imageLabel2 = new ImageLabel("path-to-file");
    imageLabel2.setPreferredSize(new Dimension(223, 310));
    ImageLabel imageLabel3 = new ImageLabel("path-to-file");
    imageLabel3.setPreferredSize(new Dimension(223, 310));
    d.gridx = 1;
    jpPack.add(imageLabel2, d);
    d.gridy = 1;
    jpPack.add(imageLabel3, d);

    imageLabel1.addMouseListener(this);
    imageLabel2.addMouseListener(this);
    imageLabel3.addMouseListener(this);

    //223, 310 are the aspect values for a card image, width, height
    //these need to be maintained as the GUI size changes

    }

}


class ImageLabel extends JLabel {
   Image image;
   ImageObserver imageObserver; 

   // constructor with filename     
   ImageLabel(String filename) {
      ImageIcon icon = new ImageIcon(filename);
      image = icon.getImage();
      imageObserver = icon.getImageObserver();
   }

   // constructor with icon
   ImageLabel(ImageIcon icon) {
      image = icon.getImage();
      imageObserver = icon.getImageObserver();
   }

   // overload setIcon method
   void setIcon(ImageIcon icon) {
      image = icon.getImage();
      imageObserver = icon.getImageObserver();
   }

   // overload paint()
   public void paint( Graphics g ) {
       super.paint( g );
       g.drawImage(image,  0 , 0 , getWidth() , getHeight() , imageObserver);

   }

}
由于某些原因,框架的组件没有默认的调整大小属性,因此当框架调整大小时,组件不会执行任何操作。我不确定我做错了什么或错过了什么,但很明显我遗漏了什么

另外,如果有人知道的话,图像标签会占用周围额外的空间。默认情况下,填充设置为0,所以我不确定为什么它会在它们周围创建一个边框

谢谢

为纪尧姆编辑:

我知道如果我想独立运行main,它是必需的,它当前是另一个应用程序的一部分,并且可以从中单独调用。为了完整性,在没有main的情况下发布它可能不是最好的决定,但无论如何,这不会是一个大问题

您的代码删除了实际显示图片的部分。“文件路径”应替换为实际的图像文件路径,以便显示图像。当它仅仅是文本时,很难看到手头的问题

当正确显示图像并尝试调整整个GUI的大小时,您会注意到图像没有收缩。它保持其首选大小,并且在变小时会出现问题。在我的代码中,当它不能显示至少首选大小时,它会完全停止显示图片。在您的代码中,当图片缩小时,它会切断部分图片

我想让它实际调整包含图片的JLabel的大小,这样随着GUI的调整,图像也会随之调整大小。这是必要的,图像收缩相应的为我的程序。用户最终将拥有基于单击图像的功能,因此仅显示部分图像或部分图像根本不行

请再次尝试您的代码/我的代码,并复制我遇到的问题,使用图片进行测试,以便我们能够找到正确的解决方案。谢谢

  • JFrame.setVisible(true)
    应该是您调用的最后一行
  • GridBagLayout
    可以根据帧大小调整组件的大小,只要使用
    weightx/weighty
    fill
  • 更新:

  • 忘记设置首选大小吧,这只会导致GUI问题
  • 如果使用LayoutManager(这是一个非常好的主意),请忘记调用setSize()/setBounds()/setLocation(),LayoutManager仍将覆盖它们
  • 您需要注意图像的大小调整,以保持原始图像的比例
  • 如果使用weightx/weighty,还应使用
    anchor
    和/或
    fill
  • 使用
    frame.pack()
    正确调整框架大小
  • 使用
    setExtendedState()
    最大化帧
  • 顺便说一句,这意味着您可以为其他人创建一个可运行的示例,包括将图像的本地路径更改为在线URL(请参见下面的示例)

    通过以下代码片段,一切似乎都正常工作:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.TextField;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.SwingUtilities;
    import javax.swing.text.DefaultStyledDocument;
    import javax.swing.text.StyledDocument;
    
    public class DraftGUI implements MouseListener {
    
        private static final String IMAGE_URL = "http://images.paramountbusinessjets.com/space/spaceshuttle.jpg";
        private JPanel jpPack;
        private JPanel jpCards;
        private JPanel jpInfo;
        private JPanel jpChat;
        private TextField tf;
        private StyledDocument doc;
        private JTextPane tp;
        private JScrollPane sp;
    
        @Override
        public void mousePressed(MouseEvent e) {
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
        }
    
        public DraftGUI() throws MalformedURLException {
    
            final JFrame frame = new JFrame("Draft");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            // set the content pane, we'll add everything to it and then add it to the frame
            JPanel contentPane = new JPanel();
            contentPane.setLayout(new GridBagLayout());
    
            // creates some panels with some default values for now
            JPanel jpCards = new JPanel(new BorderLayout());
            jpCards.setBackground(Color.BLUE);
    
            JPanel jpInfo = new JPanel();
            jpInfo.setBackground(Color.GREEN);
    
            JPanel jpPack = new JPanel(new GridBagLayout());
            jpPack.setBackground(Color.RED);
    
            // grab some info to make the JTextPane and make it scroll
            tf = new TextField();
            doc = new DefaultStyledDocument();
            tp = new JTextPane(doc);
            tp.setEditable(false);
            sp = new JScrollPane(tp);
    
            // adding the quantities to the chat panel
            JPanel jpChat = new JPanel();
            jpChat.setLayout(new BorderLayout());
            jpChat.add("North", tf);
            jpChat.add("Center", sp);
    
            // a new GridBagConstraints used to set the properties/location of the panels
            GridBagConstraints c = new GridBagConstraints();
    
            // adding some panels to the content pane
            // set it to start from the top left of the quadrant if it's too small
            c.anchor = GridBagConstraints.FIRST_LINE_START;
            c.fill = GridBagConstraints.BOTH; // set it to fill both vertically and horizontally
            c.gridx = 0; // set it to quadrant x=0 and
            c.gridy = 0; // set it to quadrant y=0
            c.weightx = 0.7;
            c.weighty = 0.3;
            contentPane.add(jpCards, c);
    
            c.gridx = 1;
            c.gridy = 0;
            c.weightx = 0.3;
            c.weighty = 0.3;
            contentPane.add(jpInfo, c);
    
            c.gridx = 0;
            c.gridy = 1;
            c.weightx = 0.7;
            c.weighty = 0.7;
            contentPane.add(jpPack, c);
    
            c.gridx = 1;
            c.gridy = 1;
            c.weightx = 0.3;
            c.weighty = 0.7;
            contentPane.add(jpChat, c);
    
            // set some necessary values
            frame.setContentPane(contentPane);
            frame.setLocationByPlatform(true);
    
            // This code works for adding an Image
            // need to learn how to specify a path not dependent on the specific users's machine
            // this is not a high priority for now though
            GridBagConstraints d = new GridBagConstraints();
            d.weightx = 1.0;
            d.weighty = 1.0;
            d.fill = GridBagConstraints.BOTH;
            d.gridx = 0;
            d.gridy = 0;
            ImageLabel imageLabel1 = new ImageLabel(new ImageIcon(new URL(IMAGE_URL)));
            jpPack.add(imageLabel1, d);
            ImageLabel imageLabel2 = new ImageLabel(new ImageIcon(new URL(IMAGE_URL)));
            d.gridx++;
            jpPack.add(imageLabel2, d);
    
            ImageLabel imageLabel3 = new ImageLabel(new ImageIcon(new URL(IMAGE_URL)));
            d.gridy++;
            jpPack.add(imageLabel3, d);
    
            imageLabel1.addMouseListener(this);
            imageLabel2.addMouseListener(this);
            imageLabel3.addMouseListener(this);
            frame.pack();
            // 223, 310 are the aspect values for a card image, width, height
            // these need to be maintained as the GUI size changes
                frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        new DraftGUI();
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        public static class ImageLabel extends JPanel {
            private static int counter = 1;
            private ImageIcon icon;
            private int id = counter++;
    
            public ImageLabel(ImageIcon icon) {
                super();
                setOpaque(false);
                this.icon = icon;
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(icon.getIconWidth(), icon.getIconHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                double zoom = Math.min((double) getWidth() / icon.getIconWidth(), (double) getHeight() / icon.getIconHeight());
                int width = (int) (zoom * icon.getIconWidth());
                int height = (int) (zoom * icon.getIconHeight());
                g.drawImage(icon.getImage(), (getWidth() - width) / 2, (getHeight() - height) / 2, width, height, this);
                g.setFont(g.getFont().deriveFont(36.0f));
                g.drawString(String.valueOf(id), getWidth() / 2, getHeight() / 2);
            }
        }
    }
    

    您需要使用不同的布局管理器,而不是网格袋布局,因为它在尽可能尊重首选尺寸。在我看来,我不能推荐一个。目前的问题是如何确定“纵横比”,请看我的最新答案。your’s和@GuillaumePolet s之间的一个区别是,您主动缩短了标签的自调整大小:一般规则是永远不要打电话。这就是说:一个图像有一个固定的大小,如果你想缩放它,你必须实现这个缩放。再看一下,一些问题:a)imageLabel。setIcon(ImageIcon)不是覆盖标签。setIcon(Icon)b)在swing中,覆盖paintComponent而不是paints。你解决了这个问题吗?请随意回答您自己的问题。我尝试了代码,但它不起作用。至少,它和我已经拥有的没有什么不同。权重和填充属性已经设置好了,所以您所做的只是添加一个setVisible和一个main(这是不必要的,我用其他方式调用它)。您还取出了ImageLabel的代码,我添加了该代码,以使图片在面板内自行调整大小。还有其他想法吗?@MichaelYousef对我来说很有效。我删除了所有不相关的部分,并添加了一个
    main
    (这是基本的!),这实际上是您工作的一部分:只显示必要的内容,并提供一个“可运行”的示例(请参见什么是一个示例)。如果它对你不起作用,请专注于解释什么不起作用以及你会期望什么。我更新了原始帖子以反映我的需要,因为我没有足够的空间放在这里。非常感谢纪尧姆,代码工作起来很有魅力。我仍然要做一些最大和最小尺寸的事情,但那应该不会太糟糕。看起来我们之前的页面有点不对劲。它的大小很好,我非常激动。再次感谢你。@MichaelYousef没问题。很高兴我能帮助你。