简体   繁体   中英

JLabel.setBounds(); is producing non satisfactory results in java code

This is a part of my java code, in this code I basically want to move a banner from left to right until the banner exits completely from the JFrame, so therefore I am increasing the horizontal location of the banner by "move" ("move" is variable in the code) in each iteration of the loop. The problem is that the value returned by (frame.getWidth()+200)/360 is of double type but setBounds(); method can not receive double type argument therefore I am casting int type to "move", in the result of this the the loop terminates before the banner completely exits from JFrame. The problem can be solved by setting the loop condition as i!=frame.getWidth()+200; but I have to run the loop 360 times. So please help.

import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class A {


    public static void main(String arg[]) throws Exception {
        new A();
    }

    public A() throws Exception {

        JFrame frame = new JFrame();
        JLabel banner = new JLabel();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.getContentPane().setBackground(Color.BLACK);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        banner.setOpaque(true);
        banner.setBounds(-200,20,200,20);
        frame.add(banner);
        frame.setVisible(true);
        double move = (frame.getWidth()+200)/360; 

        for(int i=1; i<=360; i++) {
            banner.setLocation(banner.getX()+(int)move,20);
            frame.getContentPane().revalidate();
            frame.getContentPane().repaint();
            Thread.sleep(25);   
        }
    }

}

the value returned by (frame.getWidth()+200)/360 is of double type

No, getWidth() returns an int , so the value returned by the whole expression is also of type int . You've lost the decimal places before implicitely casting to double .

You shouldn't (re-)use the rendered position for your calculations. The rounding errors will accumulate this way. Instead, you should calculate with high precision and round to int only for rendering.

Your code with small changes so that it should work as expected:

import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class A {


    public static void main(String arg[]) throws Exception {
        new A();
    }

    public A() throws Exception {

        JFrame frame = new JFrame();
        JLabel banner = new JLabel();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.getContentPane().setBackground(Color.BLACK);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        banner.setOpaque(true);
        banner.setBounds(-200,20,200,20);
        frame.add(banner);
        frame.setVisible(true);
        double start = banner.getX(); // start position
        double move = (frame.getWidth()+200)/360d; // d for double literal

        for(int i=1; i<=360; i++) {
            double x = start+(i*move); // calculate new position in double
            banner.setLocation((int) Math.round(x),20); // render in int
            frame.getContentPane().revalidate();
            frame.getContentPane().repaint();
            Thread.sleep(25);   
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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