简体   繁体   English

Java Swing Frame有点落后吗?

[英]Java Swing Frame is a tad off?

I have a simple animation code that creates a meter type rectangle effect. 我有一个简单的动画代码,可以创建一个仪表类型的矩形效果。 I would like to create it so that it fills a panel completely. 我想创建它,使其完全填充面板。 I am so close, but it extends past the frame on the bottom. 我很近,但它延伸到底部的框架之外。 What am I missing? 我想念什么?

public class Main {

public static void main(String[] args) {

    JFrame frame = new JFrame("Pong");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new GridLayout(1,2));
    frame.setSize(500, 500);

    //MouseTest test = new MouseTest();
    Test test2 = new Test(frame.getWidth(), frame.getHeight(), frame.getHeight(), 50);
    //frame.add(test);
    frame.add(test2);

    frame.setVisible(true);

    }
}

public class Test extends JPanel implements ActionListener, MouseListener{

int y = 0, width, height, dy=0, maxHeight;
int BOTTOM;
Timer timer;

public Test(int width, int height, int BOTTOM, int SPEED){
    setBackground(Color.BLUE);
    this.width = width;
    maxHeight = height;
    this.BOTTOM = BOTTOM;

    addMouseListener(this);

    timer = new Timer(1000/SPEED, this);
    timer.start();

   }
 public void move(){

    if(y>=maxHeight){
        dy = -1;
    }
    if(y<=0)
    {
        dy = 1;
    }
    y+=dy;
    height+=dy;
    //System.out.println(y);
    repaint();

}

public void paintComponent(Graphics g){

    super.paintComponent(g);
    if(y<=maxHeight/2) {
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - y, width, height);
    }
    if(y>=maxHeight/2 && y<(maxHeight/10)*9){
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - y, width, height-(maxHeight/2));
    }
    if(y>=(maxHeight/10)*9){
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM-(9*(maxHeight/10)), width, (4*maxHeight)/10);
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - y, width, height-(9*(maxHeight)/10));
    }
        for(int i = 1; i<6; i++)
            g.fillRect(0, BOTTOM - (i*(maxHeight/5)), width, 10);

    System.out.println(y);



}

Your panel takes up less room than your JFrame , because your frame has a title bar and window borders. 面板占用的空间少于JFrame ,因为您的框架具有标题栏和窗口边框。 You can just query in your paint method for the correct width and height used by the 'JPanel' with your JPanel 's getWidth() and getHeight() (in other words, your JFrame's width and height is not the same as your JPanel's width and height, even though the JPanel takes up all the space within the frame visually between the borders). 您可以在paint方法中查询JPanel使用的JPanelgetWidth()getHeight()正确的宽度和高度(换句话说,JFrame的宽度和高度与JPanel的宽度不同)和高度,即使JPanel在边框之间视觉上占据了框架中的所有空间)。

Alternatively, if you did have logic where this was not possible, you could query the size of the insets of the frame , and subtract the left and right inset values from the width, and pass that as the width, and do the same for the height with the top and bottom inset values. 另外,如果您确实有逻辑无法做到这一点,则可以查询插入大小,然后从宽度中减去左右插入值,然后将其作为宽度传递,并对顶部和底部插入值的高度。

  • Override getPreferredSize of your JPanel , this will helps the layout manager determine the best way to layout your component 覆盖JPanel getPreferredSize ,这将帮助布局管理器确定布局组件的最佳方法
  • Use JFrame#pack to wrap the frame borders around the view 使用JFrame#pack将框架边框包裹在视图周围
  • Use getWidth and getHeight to get the actual size the panel. 使用getWidthgetHeight获取面板的实际大小。 You should do this whenever you need to know these values, don't store them for long periods, as the values can change 每当您需要了解这些值时都应该这样做,不要长时间存储它们,因为这些值可能会发生变化
  • You should also have a read through Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? 您还应该通读我是否应该避免在Java Swing中使用set(Preferred | Maximum | Minimum)Size方法?

This is basic example based on you code... 这是基于您的代码的基本示例...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test1 {

    public static void main(String[] args) {
        new Test1();
    }

    public Test1() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int yPos;
        private int dy = 1;
        private int bottom = 50;

        public TestPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    move();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }

        public void move() {

            if (yPos >= getHeight()) {
                dy = -1;
            }
            if (yPos <= 0) {
                dy = 1;
            }
            yPos += dy;
            repaint();

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int maxHeight = getHeight();
            int width = getWidth();
            int height = maxHeight;
            if (yPos <= maxHeight / 2) {
                g.setColor(Color.green);
                g.fillRect(0, bottom - yPos, width, height);
            }
            if (yPos >= maxHeight / 2 && yPos < (maxHeight / 10) * 9) {
                g.setColor(Color.green);
                g.fillRect(0, bottom - (maxHeight / 2), width, maxHeight / 2);
                g.setColor(Color.green);
                g.fillRect(0, bottom - yPos, width, height - (maxHeight / 2));
            }
            if (yPos >= (maxHeight / 10) * 9) {
                g.setColor(Color.green);
                g.fillRect(0, bottom - (maxHeight / 2), width, maxHeight / 2);
                g.setColor(Color.green);
                g.fillRect(0, bottom - (9 * (maxHeight / 10)), width, (4 * maxHeight) / 10);
                g.setColor(Color.green);
                g.fillRect(0, bottom - yPos, width, height - (9 * (maxHeight) / 10));
            }
            for (int i = 1; i < 6; i++) {
                g.fillRect(0, bottom - (i * (maxHeight / 5)), width, 10);
            }

        }
    }

}

Another way to go is to use pack(). 另一种方法是使用pack()。 It sets the size of the frame to be the size of the frame's contents. 它将框架的大小设置为框架内容的大小。 In your code it would look like this: 在您的代码中,它看起来像这样:

frame.add(test2);
frame.pack();

If you do it this way, you don't need the frame.setSize() call. 如果以这种方式进行操作,则不需要frame.setSize()调用。 You can add the panel either with .add() as you've done or with: 您可以添加.add()或添加以下内容来添加面板:

frame.setContentPane(test2);

So I combined both your comments and got it to work correctly. 因此,我结合了您的评论并使其正常工作。 Here is the code that works. 这是有效的代码。

public class Main {

public static void main(String[] args) {

    JFrame frame = new JFrame("Pong");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new GridLayout(1,2));
    Insets inset = frame.getInsets();


    Test test2 = new Test(200-(inset.right + inset.left), 200 -(inset.top + inset.bottom), 200, 50);
    frame.setContentPane(test2);
    frame.pack();

    frame.setVisible(true);

}
}

public class Test extends JPanel implements ActionListener, MouseListener{

int y = 0, width, height, dy=0, maxHeight;
int BOTTOM;
Timer timer;
Dimension size;
Insets inset;

public Test(int width, int height, int BOTTOM, int SPEED){
    size = new Dimension(width, height);
    setBackground(Color.BLUE);
    setPreferredSize(size);
    inset = this.getInsets();
    this.width = width-(inset.right+inset.left);
    maxHeight = height;
    this.BOTTOM = BOTTOM - (inset.bottom+inset.top);

    addMouseListener(this);

    timer = new Timer(1000/SPEED, this);
    timer.start();

   }
public void move(){

    if(y>=maxHeight){
        dy = -1;
    }
    if(y<=0)
    {
        dy = 1;
    }
    y+=dy;
    height+=dy;
    //System.out.println(y);
    repaint();

}

public void paintComponent(Graphics g){

    super.paintComponent(g);
    if(y<=maxHeight/2) {
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - y, width, height);
    }
    if(y>=maxHeight/2 && y<(maxHeight/10)*9){
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - (maxHeight / 2), width, maxHeight / 2);
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - y, width, height-(maxHeight/2));
    }
    if(y>=(maxHeight/10)*9){
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM-(9*(maxHeight/10)), width, (4*maxHeight)/10);
        g.setColor(Color.green);
        g.fillRect(0, BOTTOM - y, width, height-(9*(maxHeight)/10));
    }

    g.setColor(Color.white);
        for(int i = 1; i<6; i++)
            g.fillRect(0, BOTTOM - (i*(maxHeight/5)), width, 5);

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM