Question

I'm having an issue with a class project that I'm currently working on. Basically, we are creating a GUI where you select the style of text you want after typing in something in a JTextArea. Once you hit a display button, it should display the updated type using drawString() in the GUI. Before adding in the paint method, everything worked OK (no actions yet either). However now, I have a large area with nothing on it (no menu bar or button), and when I kind of move the mouse around or click, the button and textArea will appear. I think it is because it is trying to paint something automatically? Does anyone know how to fix this?

Here is my entire code below, the paint method and actionPerformed are the only real non gui pieces:


/*
 - Menu bar at the top with Font, Style, Size
 - Font = Monospaced, SansSerif, Serif
 - Get two more custom fonts using Font createFont (.ttf) files
 - Style = Bold, Italic, Plain
 - Size = 9, 10, 12, 14, 16, 24, 32
 - Create a text field in the center where user inputs text
 - Create a display button that updates with selected fonts
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FontChanger extends JFrame implements ActionListener {

    /* INSTANCE VARIABLES */
    private final int WIDTH = 400;
    private final int HEIGHT = 400;
    private JTextArea userInput;
    private JButton displayButton; // once pressed, font/size/style changes
    private JMenuBar menuBar;
    private JMenu fontMenu, styleMenu, sizeMenu; // main menu items
    private JMenuItem monospacedFont, sansSerifFont, serifFont, arialFont, helveticaFont; // fonts for fontMenu
    private JMenuItem boldStyle, italicStyle, plainStyle; // styles for fonts
    private JMenuItem nine, ten, twelve, fourteen, sixteen, twentyFour, thirtyTwo; // sizes for fonts
    private JPanel textPanel, buttonPanel, displayPanel; // where button & text field go
    private int fontSize = 8; // default, will be updated when user clicks on it
    private String fontName = "MonoSpaced"; // will be updated when user clicks on a font name and added to paint
    private boolean bold = false, italic = false, plain = true; // either true or false depending on what has been selected


    /* CONSTRUCTORS */
    public FontChanger() {
        // main window
        super("Font Changer Program");
        setSize(WIDTH, HEIGHT);
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // panel
        textPanel = new JPanel();
        textPanel.setBackground(Color.WHITE);
        buttonPanel = new JPanel();
        buttonPanel.setBackground(Color.WHITE);

        // menu
        menuBar = new JMenuBar();
        // font menu
        fontMenu = new JMenu("Font");
        monospacedFont = new JMenuItem("Mono Spaced");
        monospacedFont.setActionCommand("Monospaced"); // so we can set font easier in actionPerformed
        monospacedFont.addActionListener(this);
        fontMenu.add(monospacedFont);
        sansSerifFont = new JMenuItem("Sans Serif");
        sansSerifFont.setActionCommand("SansSerif");
        sansSerifFont.addActionListener(this);
        fontMenu.add(sansSerifFont);
        serifFont = new JMenuItem("Serif");
        serifFont.setActionCommand("Serif");
        serifFont.addActionListener(this);
        fontMenu.add(serifFont);
        arialFont = new JMenuItem("Arial");
        arialFont.addActionListener(this);
        fontMenu.add(arialFont);        
        helveticaFont = new JMenuItem("Helvetica");
        helveticaFont.addActionListener(this);
        fontMenu.add(helveticaFont);
        // style menu
        styleMenu = new JMenu("Style");
        boldStyle = new JMenuItem("Bold");
        boldStyle.addActionListener(this);
        styleMenu.add(boldStyle);
        italicStyle = new JMenuItem("Italic");
        italicStyle.addActionListener(this);
        styleMenu.add(italicStyle);
        plainStyle = new JMenuItem("Plain");
        plainStyle.addActionListener(this);
        styleMenu.add(plainStyle);
        // size menu
        sizeMenu = new JMenu("Size");
        nine = new JMenuItem("9");
        nine.addActionListener(this);
        sizeMenu.add(nine);
        ten = new JMenuItem("10");
        ten.addActionListener(this);
        sizeMenu.add(ten);        
        twelve = new JMenuItem("12");
        twelve.addActionListener(this);
        sizeMenu.add(twelve);
        fourteen = new JMenuItem("14");
        fourteen.addActionListener(this);
        sizeMenu.add(fourteen);
        sixteen = new JMenuItem("16");
        sixteen.addActionListener(this);
        sizeMenu.add(sixteen);
        twentyFour = new JMenuItem("24");
        twentyFour.addActionListener(this);
        sizeMenu.add(twentyFour); 
        thirtyTwo = new JMenuItem("32");
        thirtyTwo.addActionListener(this);
        sizeMenu.add(thirtyTwo); 

        // text field
        userInput = new JTextArea("Enter a phrase here and click display", 5, 10);
        userInput.setBorder(BorderFactory.createLineBorder(Color.black, 2));
        textPanel.add(userInput);

        // display button
        displayButton = new JButton("Display");
        displayButton.addActionListener(this);
        buttonPanel.add(displayButton);

        // add to window
        menuBar.add(fontMenu);
        menuBar.add(styleMenu);
        menuBar.add(sizeMenu);
        setJMenuBar(menuBar);
        add(textPanel, BorderLayout.NORTH);
        add(buttonPanel, BorderLayout.CENTER);
        setVisible(true);   
    }

    /* OTHER METHODS */
    public void actionPerformed(ActionEvent e) {
        String menuString = e.getActionCommand();
        // check font type
        if(menuString.equals("Monospaced") || menuString.equals("SansSerif") || menuString.equals("Serif")
               || menuString.equals("Arial") || menuString.equals("Helvetica")) {
            fontName = menuString; // converts string chosen into a font we can use
        } // no else
        // check size of font
        if(menuString.equals("9") || menuString.equals("10") || menuString.equals("12")
               || menuString.equals("14") || menuString.equals("16") || menuString.equals("24") 
               || menuString.equals("32")) {
            fontSize = Integer.parseInt(menuString); // converts the string to a size we can use
        }
        // check style
        if(menuString.equals("Bold")) {
            bold = !bold; // so user can click it on and off
        } else if(menuString.equals("Italic")) {
            italic = !italic;
        } else if(menuString.equals("Plain")) {
            plain = !plain; 
        }
        // display button
        if(menuString.equals("Display")) {
            repaint(); // uses our paint method to redraw the string
        } 
    }
    // draws the String to an area
    public void paint(Graphics g) {
        Font userFont = null; 
        if(plain == true && bold == false && italic == false) {
            userFont = new Font(fontName, Font.PLAIN, fontSize); // for plain font
        } else if(plain == false && bold == true && italic == false) {
            userFont = new Font(fontName, Font.BOLD, fontSize); // for bold font
        } else {
            userFont = new Font(fontName, Font.ITALIC, fontSize); // for italic font
        }
        // draw to the text field
        g.setFont(userFont); // sets font to one of the choices
        g.drawString(userInput.getText(), 50, 200); // draws new text
    }

    // tester
    public static void main(String[] args) {
        FontChanger test = new FontChanger();
    }

}

Edit:

Here are the blocks of code that are affecting the program(actionPerformed and Paint):

 
    `public void actionPerformed(ActionEvent e) {
        String menuString = e.getActionCommand();
        // display button
        if(menuString.equals("Display")) {
            repaint(); // uses our paint method to redraw the string
        } 
    }

    // draws the String to an area
    public void paint(Graphics g) {
        Font userFont = null; 
        if(plain == true && bold == false && italic == false) {
            userFont = new Font(fontName, Font.PLAIN, fontSize); // for plain font
        } else if(plain == false && bold == true && italic == false) {
            userFont = new Font(fontName, Font.BOLD, fontSize); // for bold font
        } else {
            userFont = new Font(fontName, Font.ITALIC, fontSize); // for italic font
        }
        // draw to the text field
        g.setFont(userFont); // sets font to one of the choices
        g.drawString(userInput.getText(), 50, 200); // draws new text
    }`
    

The issue is with where it is painting to since I don't think repaint() is being called until I hit display.

Edit 2: Shoot. The reason everything was acting weird (besides my lack of GUI knowledge) was because I forgot to call super.paint(g); in the paint method before everything.

Was it helpful?

Solution

You're doing several things wrong:

  • You're trying to draw directly in the JFrame
  • You're overriding JFrame's paint method without calling the super method.
  • You obviously have tried to do this without going through any of the Swing Graphics tutorials.

I suggest that you fix these guys:

  • Draw in a JPanel not a JFrame, and then display that JPanel in your JFrame.
  • Override the JPanel's paintComponent(...) method, not its paint method.
  • Be sure to call the super's paintComponent method as the first method call in your override.
  • And most important, look at the tutorials before moving forward. From my own experience, I can tell you that you can't simply guess how to do this and hope it will work. Google Java Swing Graphics Tutorial, and you should get decent hits.

You'll find decent links here for instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top