JPanel的位置和大小根据屏幕大小而变化 [英] JPanel positions and sizes changes according to screensize

查看:193
本文介绍了JPanel的位置和大小根据屏幕大小而变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

程序根据屏幕分辨率或计算机大小运行。当我在具有特定大小的监视器的计算机中运行它时,它将相应地改变。我的问题是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;

公共类主页扩展JFrame {

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

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

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

public Homepage()抛出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();
返回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);

}

}

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

解决方案

跟进@MadProgrammer评论:



您真的需要学习如何使用布局管理器。设置尺寸不是可行的方法,因为它们在不同的机器上会有不同的表现。



关于布局管理器的一个重要事项是布局是否符合其优先尺寸内部组件。那些不尊重尺寸的产品会拉伸部件。某些布局可能无法拉伸其组件,但会在主容器拉伸时将它们放置在开放空间内的默认位置。



要获得所需的结果,它是有时也需要嵌套具有不同布局的容器,这可以利用两个或更多布局。



我知道这不是你的问题的答案,但是我认为你可能仍然会对你的问题有所了解,以及如何通过使用布局管理器来实现你想要的目标。



下面我刚刚编造一些主要布局管理器的不同性质的快速示例。你可以玩它。请注意,主 JFrame 使用默认的 BorderLayout 。我只是明确地将布局设置为 BorderLayout ,这样你就可以看到哪种布局会产生效果。



另外看看在

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

import javax.swing。*;

公共类TestingLayoutManagers {

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

私人决赛JButton northButton =新JButton(North Button);
私人决赛JButton southButton =新JButton(南按钮);
私人决赛JButton centerButton =新JButton(中心按钮);
私人决赛JButton eastButton =新JButton(东部按钮);

私人决赛JButton menuButton1 =新JButton(菜单项1);
私人决赛JButton menuButton2 =新JButton(菜单项2);
私人决赛JButton menuButton3 =新JButton(菜单项3);
私人决赛JButton menuButton4 =新JButton(菜单项4);
私人决赛JButton menuButton5 =新JButton(菜单项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(方框);
westBoxLayoutPanel.setBorder(BorderFactory.createTitledBorder(Box Layout));

JFrame frame = new JFrame(Test Layout Managers);
frame.setLayout(new BorderLayout()); //这是deafault布局
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();
});
}
}


The program runs with its size according to screen resolution or size of the computer. When I run it in a computer with specific size of its monitor it will change accordingly. My problem is the positioning and size of a JPanel, or any object inside the frame, to adopt on the change of screen size.

So whenever I will present my program on any monitor with different sizes the components will still be organized and placed as what I've originally designed it. But here I'm testing it with one JPanel named displayMenu. In which it displays a panel colored in green.

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

}

}

Also, it looks like my background was not totally spread throughout the frame. There is a white line on the top but the rest is the background. What should I gonna do? Thanks for help!

解决方案

Following up with @MadProgrammer comment:

You really need to learn how to use Layout Mangers. Setting sizes is not the way to go, as they will perform different on different machines.

One important thing to know about Layout Managers are which layouts respect the preferred sizes of its internal components. The ones that do not respect the sizes, will stretch the components. Some layouts may not stretch their components, but will position them in a default location within the open space, when the main container is stretched.

To get desired results, it is also sometimes necessary to nest containers with different layouts, this taking advantage of two or more layouts.

I know this isn't really much of an answer to your question, but I thought you may still gain some insight to your problem, and how you can achieve what you are trying to, with the use of Layout Managers.

Below I just made up a quick example of the different natures of some of the main Layout Managers. You can play around with it. Note the main JFrame is using the default BorderLayout. I only explicitly set the layout as BorderLayout so you can see which layout causes the effect.

Also have a look at Laying out Components Withing a Container to learn more about how to use different Layout Managers. Avoid using the null layouts and trying to position everything yourself. Let the layouts do it for you, as Swing was built to used with Layout Managers.


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

这篇关于JPanel的位置和大小根据屏幕大小而变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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