简体   繁体   中英

Drawing Lines with JFrames and JPanels

I have a program with mutliple JFrames. I want to draw lines on only one of these. It's a simple hangman program, so only the actual game page should have these lines on it. (These lines will make up the noose part so should be drawn every time right away.) Attempted to add a painter class to the JFrame in question based on some other similar QAs I found, but it doesn't seem to be working.

package hangman;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;


class Painter extends JPanel{

    public Painter(){

    }
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawString("This is a test.",50,50);
        g.drawLine(20, 80, 20, 200);

    }
}

public class Hangman{

    public static void main(String[] args) throws InterruptedException{
         hangman();
    }

    // method: hangman()
    // purpose: create windows that make the Hangman game
    private static void hangman() {

        //Timer
        final DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        int interval = 1000; // 1000 ms

        Calendar now = Calendar.getInstance();
        JLabel time = new JLabel(dateFormat.format(now.getTime()));
        time.setBounds(450, -50, 200, 125);

        Timer timer = new Timer(interval, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Calendar now = Calendar.getInstance();
                time.setText(dateFormat.format(now.getTime()));
            }
        });

        timer.start();


        //Frames
        JFrame titleFrame = new JFrame("Hangman"); 
        JFrame mainMenuFrame = new JFrame("Hangman"); 
        JFrame creditsFrame = new JFrame("Hangman"); 
        JFrame highScoreFrame = new JFrame("Hangman");
        JFrame playGame = new JFrame("Hangman");

        creditsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        titleFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        mainMenuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        highScoreFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        playGame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Labels
        final JLabel titleText = new JLabel();
        final JLabel teamText = new JLabel();  
        final JLabel jennaBarrett = new JLabel();
        final JLabel lennyYang = new JLabel();
        final JLabel rachelFrodsham = new JLabel();
        final JLabel titleCredit = new JLabel();
        final JLabel highScores = new JLabel();
        final JLabel hangmanTitle = new JLabel();

        ImageIcon pastaIcon = new ImageIcon("Images/pasta.png");
        JLabel pastaImage = new JLabel(pastaIcon); 

        titleText.setText("CS245 Quarter Project"); 
        titleCredit.setText("Credits");
        teamText.setText("By: Pasta Party");  
        jennaBarrett.setText("Jenna Barret, 010805821");
        lennyYang.setText("Lenny Yang, 010265034");
        rachelFrodsham.setText("Rachel Frodsham, 009922783");
        highScores.setText("High Scores");
        hangmanTitle.setText("Hangman");

        titleText.setFont(new Font("Arial", Font.BOLD, 30));
        titleCredit.setFont(new Font("Arial", Font.BOLD, 20));
        highScores.setFont(new Font("Arial", Font.BOLD, 20));
        hangmanTitle.setFont(new Font("Serif", Font.BOLD, 40));

        //Buttons
        JButton playButton = new JButton("Play");  
        JButton highScoreButton = new JButton("High Score");  
        JButton creditsButton = new JButton("Credits");
        JButton backButtonCF = new JButton("Back");
        JButton backButtonHS = new JButton("Back");

        //Positioning
        titleText.setBounds(130,50,500,150);
        teamText.setBounds(250,300,200,50);
        teamText.setBounds(250,300,150,50);
        playButton.setBounds(400,185,150,30);  
        highScoreButton.setBounds(400,235,150,30);  
        creditsButton.setBounds(400,285,150,30);
        backButtonHS.setBounds(25,300,95,30);   
        backButtonCF.setBounds(25,300,95,30);
        jennaBarrett.setBounds(250,125,200,100);
        lennyYang.setBounds(250,150,200,100);
        rachelFrodsham.setBounds(250,175,200,100);
        pastaImage.setBounds(10, 0, 400, 400);
        titleCredit.setBounds(250,75,100,100);
        highScores.setBounds(250,10,300,150);
        hangmanTitle.setBounds(25,-10,500,100);

        //Listeners
        new java.util.Timer().schedule(new java.util.TimerTask() {
                @Override
                public void run() {
                    titleFrame.setVisible(false);
                    mainMenuFrame.setVisible(true);
                }
            },
            4500 
        );

        highScoreButton.addActionListener(new ActionListener(){  
            public void actionPerformed(ActionEvent e){  
                mainMenuFrame.setVisible(false);
                highScoreFrame.setVisible(true);
            }  
        });

        playButton.addActionListener(new ActionListener(){  
            public void actionPerformed(ActionEvent e){  
                mainMenuFrame.setVisible(false);
                playGame.setVisible(true);
            }
        });

        creditsButton.addActionListener(new ActionListener(){  
            public void actionPerformed(ActionEvent e){  
                mainMenuFrame.setVisible(false);
                creditsFrame.setVisible(true);
            }  
        });

        backButtonCF.addActionListener(new ActionListener(){  
            public void actionPerformed(ActionEvent e){  
                creditsFrame.setVisible(false);
                mainMenuFrame.setVisible(true);
            }  
        });  

        backButtonHS.addActionListener(new ActionListener(){  
            public void actionPerformed(ActionEvent e){  
                highScoreFrame.setVisible(false);
                mainMenuFrame.setVisible(true);
            }  
        });          

        //Title Frame
        titleFrame.setSize(600,400);
        titleFrame.add(titleText);  
        titleFrame.add(teamText);
        titleFrame.setLayout(null);
        titleFrame.setLocationRelativeTo(null); 
        titleFrame.setVisible(true); 


        //Main Frame
        mainMenuFrame.setSize(600,400);  
        mainMenuFrame.add(playButton); 
        mainMenuFrame.add(highScoreButton); 
        mainMenuFrame.add(creditsButton);                 
        mainMenuFrame.add(pastaImage);        
        mainMenuFrame.setLayout(null);
        mainMenuFrame.setLocationRelativeTo(null);

        //Play Frame
        playGame.setSize(600,400);  
        playGame.add(hangmanTitle); 
        playGame.setLayout(null);
        playGame.add(time);
        playGame.setLocationRelativeTo(null); 

        Painter p = new Painter();
        p.setVisible(true);
        playGame.add(p);


        //Credits Frame
        creditsFrame.setSize(600,400);
        creditsFrame.add(titleCredit);
        creditsFrame.add(jennaBarrett);
        creditsFrame.add(lennyYang);
        creditsFrame.add(rachelFrodsham);
        creditsFrame.add(backButtonCF);
        creditsFrame.setLayout(null);
        creditsFrame.setLocationRelativeTo(null); 

        //High Scores Frame
        highScoreFrame.setSize(600,400);
        highScoreFrame.add(highScores);
        highScoreFrame.add(backButtonHS);
        highScoreFrame.setLayout(null);
        highScoreFrame.setLocationRelativeTo(null); 

    }
}
//

playGame.setLayout(null); is messing you up, since when using null layouts you are fully responsible for the complete positioning and sizing of components, and you aren't setting the size or "bounds" your Painter JPanel . Comment out this line to see what I mean.

But nor should you be setting its size since in general, don't use null layouts but instead learn to use the layout managers. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.


"I have a program with mutliple JFrames"

Obligatory link to a key relevant question: The Use of Multiple JFrames, Good/Bad Practice? . So yeah if you don't want to completely annoy the users of your application, use a CardLayout here.


Other problems:

  • Not starting your GUI on the Swing event thread (the EDT or "Event Dispatch Thread")
  • Using a java.util.Timer instead of a javax.swing.Timer. Note that the latter is much more Swing thread-safe

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