【问题标题】:JPanel positions and sizes changes according to screensizeJPanel 位置和大小根据屏幕大小而变化
【发布时间】:2014-02-17 23:03:28
【问题描述】:

程序根据屏幕分辨率或计算机大小运行其大小。当我在具有特定尺寸显示器的计算机上运行它时,它会相应地改变。我的问题是 JPanel 或框架内的任何对象的定位和大小,以适应屏幕大小的变化。

因此,每当我将我的程序展示在任何尺寸不同的显示器上时,组件仍将按照我最初设计的方式进行组织和放置。但在这里,我使用一个名为 displayMenu 的 JPanel 对其进行测试。它在其中显示一个绿色的面板。

package saves.project;

import com.sun.awt.AWTUtilities;
import java.awt.*;
import java.awt.image.BufferedImage;

import java.io.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.BorderFactory;

import javax.imageio.ImageIO;

public class Homepage extends JFrame{

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Border grayline = BorderFactory.createLineBorder(Color.GRAY);;

int width = screenSize.width, height = screenSize.height;

public Homepage() throws IOException{

    super("Homepage");
    displayMenu();
    displayBackground();

}

public static BufferedImage resize(BufferedImage image, int width, int height) {

    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
    Graphics2D g2d = (Graphics2D) bi.createGraphics();
    g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
    g2d.drawImage(image, 0, 0, width, height, null);
    g2d.dispose();
    return bi;

}

public void displayBackground() throws IOException{

    JPanel pBackground = new JPanel();
    pBackground.setSize(screenSize);
    pBackground.setLayout(new FlowLayout());
    add(pBackground);

    BufferedImage header = ImageIO.read(new File("res\\bg.jpg"));
    BufferedImage resizedImage = resize(header,width,height);
    ImageIcon image = new ImageIcon(resizedImage);
    JLabel lblheader = new JLabel(image, JLabel.CENTER);
    pBackground.add(lblheader);

}

public void displayMenu() {

    JPanel pTitle = new JPanel();
    pTitle.setLayout(null);
    pTitle.setBounds(width/3, (height/2)+20, width/2, height/2);
    pTitle.setBackground(Color.GREEN);
    add(pTitle);

}

public void CreateAndShowGUI() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setUndecorated(true);
    setVisible(true);  

}

}

另外,看起来我的背景并没有完全散布在整个画面中。顶部有一条白线,其余的是背景。我该怎么办?感谢您的帮助!

【问题讨论】:

  • 不要使用组件的 setSize 或 setBounds,它们应该留给布局管理器。考虑使用类似 GridBagLayout 的东西,您需要更好地控制布局。你可能还会发现,当 HomePage 是构造函数时,组件的大小是未知的
  • 感谢您的回答!你能提供更多细节吗?在此先感谢^^我只是这里的新手:D

标签: java swing layout-manager


【解决方案1】:

跟进@MadProgrammer 评论:

您确实需要学习如何使用布局管理器。设置大小不是要走的路,因为它们在不同的机器上会表现不同。

关于布局管理器需要了解的重要一点是哪些布局尊重其内部组件的首选大小。那些不尊重尺寸的,将拉伸组件。某些布局可能不会拉伸其组件,但会在主容器拉伸时将它们放置在开放空间内的默认位置。

为了获得理想的结果,有时还需要嵌套具有不同布局的容器,这会利用两个或多个布局。

我知道这并不能很好地回答您的问题,但我认为您仍然可以通过使用布局管理器了解您的问题以及如何实现您的目标。

下面我只是简单地举例说明了一些主要布局管理器的不同性质。你可以玩弄它。注意主要的JFrame 使用默认的BorderLayout。我只是将布局显式设置为BorderLayout,这样您就可以看到是哪个布局导致了效果。

还可以查看Laying out Components Withing a Container 以了解有关如何使用不同布局管理器的更多信息。避免使用空布局并尝试自己定位所有内容。让布局为您做这件事,因为 Swing 是为与布局管理器一起使用而构建的。


import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;

import javax.swing.*;

public class TestingLayoutManagers {

    private JPanel northFlowLayoutPanel;
    private JPanel southBorderLayoutPanel;
    private JPanel centerGridBagLayoutPanel;
    private JPanel westBoxLayoutPanel;
    private JPanel eastGridLayoutPanel;

    private final JButton northButton = new JButton("North Button");
    private final JButton southButton = new JButton("South Button");
    private final JButton centerButton = new JButton("Center Button");
    private final JButton eastButton = new JButton("East Button");

    private final JButton menuButton1 = new JButton("Menu Item 1");
    private final JButton menuButton2 = new JButton("Menu Item 2");
    private final JButton menuButton3 = new JButton("Menu Item 3");
    private final JButton menuButton4 = new JButton("Menu Item 4");
    private final JButton menuButton5 = new JButton("Menu Item 5");

    public TestingLayoutManagers() {
        northFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        southBorderLayoutPanel = new JPanel(new BorderLayout());
        centerGridBagLayoutPanel = new JPanel(new GridBagLayout());
        eastGridLayoutPanel = new JPanel(new GridLayout(1, 1));
        Box box = Box.createVerticalBox();
        westBoxLayoutPanel = new JPanel();

        northFlowLayoutPanel.add(northButton);
        northFlowLayoutPanel.setBorder(BorderFactory.createTitledBorder("Flow Layout"));

        southBorderLayoutPanel.add(southButton);
        southBorderLayoutPanel.setBorder(BorderFactory.createTitledBorder("Border Layout"));

        centerGridBagLayoutPanel.add(centerButton);
        centerGridBagLayoutPanel.setBorder(BorderFactory.createTitledBorder("GridBag Layout"));

        eastGridLayoutPanel.add(eastButton);
        eastGridLayoutPanel.setBorder(BorderFactory.createTitledBorder("Grid Layout"));

        box.add(menuButton1);
        box.add(menuButton2);
        box.add(menuButton3);
        box.add(menuButton4);
        box.add(menuButton5);
        westBoxLayoutPanel.add(box);
        westBoxLayoutPanel.setBorder(BorderFactory.createTitledBorder("Box Layout"));

        JFrame frame = new JFrame("Test Layout Managers");
        frame.setLayout(new BorderLayout());      // This is the deafault layout
        frame.add(northFlowLayoutPanel, BorderLayout.PAGE_START);
        frame.add(southBorderLayoutPanel, BorderLayout.PAGE_END);
        frame.add(centerGridBagLayoutPanel, BorderLayout.CENTER);
        frame.add(eastGridLayoutPanel, BorderLayout.LINE_END);
        frame.add(westBoxLayoutPanel, BorderLayout.LINE_START);

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(
                        UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException
                    | InstantiationException
                    | IllegalAccessException
                    | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            }

            new TestingLayoutManagers();
        });
    }
}

【讨论】:

  • 老实说,我总是觉得投反对票,这样的帖子仍然建议使用BorderLayout.NORTH/SOUTH/EAST/WEST 而不是BorderLayout.PAGE_START/PAGE_END/LINE_START/LINE_END。甚至 Java 也鼓励使用后者,因为 1.4
  • 哈哈,但它仍然说 BorderLayout.SOUTH 什么时候应该是 BorderLayout.PAGE_ENDBorderLayout.LINE_START 对于 BorderLayout.EASTBorderLayout.LINE_END 对于 BorderLayout.WEST :-)
  • 哦。我从来没有收到备忘录。 :P。我会修复它。完毕。现在我需要改变我的习惯
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 2022-01-24
相关资源
最近更新 更多