I recently completed a Java course from caveofprogramming.com. It was a great course, and I learned a lot. I am trying to create a screen saver program in Java, but my graphic that is suppose to float around the screen just flicks in the middle of the screen.
Here is what I have so far:
/**
* Phoenix Hospitality Management System (PHMS)
* PHMS 001 - TME Protector
* Screen Protector Program
* Copyright (C) 2021 By Troy Marker Enterprises
* All Right Reserved
*
* NOTICE: This program was created for use of the Phoenix Hospitality Management System (PHMS). Any use outside of the PHMS
* is strictly prohibited. *
*/
package view;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import view.PhoenixColors;
/**
* Main screen protector class;
* Called by the App Controller
*
* @author Troy L. Marker
*
*/
public class Protect extends JFrame implements KeyListener, MouseMotionListener, ActionListener {
private static final long serialVersionUID = -3655698826064710315L;
private JLabel logo;
private Timer timer;
private double speed = 10.0;
private double xLoc;
private double yLoc;
private int xDirectionLogo = 1;
private int yDirectionLogo = 1;
public Protect() {
getContentPane().setBackground(PhoenixColors.BLACK);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setUndecorated(true);
timer = new Timer(20, this);
BufferedImage TMELogo = null;
try {
TMELogo = ImageIO.read(getClass().getResource("/images/TMELogo.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logo = new JLabel(new ImageIcon(TMELogo));
add(logo);
setVisible(true);
addKeyListener(this);
addMouseMotionListener(this);
timer.start();
}
private void update() {
xLoc = xDirectionLogo * speed;
yLoc = yDirectionLogo * speed;
if (xLoc < 0) {
xDirectionLogo = 1;
xLoc = 1;
} else if (xLoc > getWidth() - logo.getWidth()) {
xDirectionLogo = -1;
xLoc = getWidth() - logo.getWidth();
}
if (yLoc < 0) {
yDirectionLogo = 1;
yLoc = 1;
} else if(yLoc > getHeight() - logo.getHeight()) {
yDirectionLogo = -1;
yLoc = getHeight() - logo.getHeight();
}
logo.setLocation((int)xLoc, (int)yLoc);
repaint();
System.out.println("xLoc, yLoc: " xLoc ", " yLoc);
}
@Override
public void keyTyped(KeyEvent e) {
System.exit(0);
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
System.exit(0);
}
@Override
public void actionPerformed(ActionEvent e) {
update();
}
}
The update method is what I use to adjust the position of the image every 20 milliseconds. Please talk a look and help me find what i am missing. Thank you.
Addendum: In response to Stephens comment, I feel I need to clarify what I am doing. I am designing a computer system for the hospitality industry. I am creating my own Linux system using Linux From Scratch. I want a Java based screen saver because that is the language I am planning to write the software in. Java may not be the best language to create this system in, but I like the fact the it is a cross platform language due to the JVM. I would like to humbly request an answer to my original question, show I can find out what I am doing wrong, if I get the answer, I very well could help me with future projects. Thank you again.
CodePudding user response:
The problem is the JLabel is added as the only content of the JFrame, so it is resized to be the full size of the JFrame. I printed out size on my machine and the JFrame
's getWidth()
and getHeight()
return 1536x864 while the JLabel
's logo.getWidth()
and logo.getHeight()
are also 1536x864.
You might be able to control the size of the JLabel
, but it seems to me that it would be easier to simple add a JPanel
to your layout and override its paintComponent(Graphics g)
method to call super.paintComponent(g);
and then just draw the BufferedImage
wherever you want within it.
CodePudding user response:
Commit this code to memory (or save it somewhere so you could reuse this pattern). This is the correct way to implement the main application frame for a Swing application.
public class FrameDemo {
private static void createAndShowGUI() {
JFrame frame = new JFrame("My Basic Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // To REALLY close your app
JPanel emptyPanel = new JPanel();
emptyPanel.setPreferredSize(new Dimension(175, 100));
frame.getContentPane().add(emptyPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule your app to run in the Event Dispatcher Thread
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
After you do this, modify this code following @David Conrad's advice. Don't forget to create a custom class for your panel and add the event handlers where they belong.