Home > Blockchain >  How to get a screen saver working in Java
How to get a screen saver working in Java

Time:12-02

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. What am I missing?

Addendum

In response to Stephen's 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.

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.

  • Related