0
votes

I have created a basic GUI which has 2 JCheckButtons (bold, italic) and 3JRadioButtons in a button group of font styles (times, helvetica, courier). There is also a textfield which will display a string of the font style, such as times, in that style, and if the bold or italic buttons are pressed then the text will also be bold or italic (or both). So far I have managed to add action listeners which copy the font name from the radio buttons to the textfield but I am having trouble making this text be in the associated font style. I also am having trouble with the functions of my bold and italic buttons.

Here is the code for my GUI layout (the layout is how I want it to be, only problem is with the functionality of my buttons:

package weekTwo;
import javax.swing.*;
import java.awt.*;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class taskTwo {

public static void main(String[] args) {
    JFrame window = new JFrame("Font Chooser");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setSize(500, 100);

    FontSetter fontSetter = new FontSetter();

    Container pane = window.getContentPane();
    pane.setLayout(new GridBagLayout());

    GridBagConstraints gbc = new GridBagConstraints();

    JTextField text = new JTextField();
    gbc.gridx = 2;
    gbc.gridy = 2;
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.insets = new Insets(0, 0, 5, 5); //padding constraints
    gbc.fill = GridBagConstraints.BOTH;   //text field fills cell
    pane.add(text, gbc);

    JCheckBox bold = new JCheckBox("Bold");
    gbc.gridx = 0; //sets x position to 0
    gbc.gridy = 1;
    bold.addActionListener(new Bold(fontSetter, text));
    pane.add(bold, gbc);

    JCheckBox italic = new JCheckBox("Italic");
    gbc.gridx = 0;
    gbc.gridy = 3;
    italic.addActionListener(new Italic(fontSetter, text));
    pane.add(italic, gbc);

    JRadioButton times = new JRadioButton("Times", true);
    gbc.gridx = 1;
    gbc.gridy = 0;
    times.addActionListener(new Times(fontSetter, text));
    pane.add(times, gbc);

    JRadioButton helvetica = new JRadioButton("Helvetica", false);
    gbc.gridx = 1;
    gbc.gridy = 2;
    helvetica.addActionListener(new Helvetica(fontSetter, text));
    pane.add(helvetica, gbc);

    JRadioButton courier = new JRadioButton("Courier", false);
    gbc.gridx = 1;
    gbc.gridy = 4;
    courier.addActionListener(new Courier(fontSetter, text));
    pane.add(courier, gbc);

    ButtonGroup fonts = new ButtonGroup();  //now only one of these buttons can be selected at once
    fonts.add(times);
    fonts.add(helvetica);
    fonts.add(courier);

    JButton ok = new JButton("OK");
    gbc.gridx = 3;
    gbc.gridy = 2;
    //ok.addActionListener();
    pane.add(ok, gbc);

    window.setVisible(true);
}
}

And here are my classes for my action listeners:

class Bold implements ActionListener {

private final FontSetter fontSetter;
private final JTextField textfield;

Bold(FontSetter fontSetter, JTextField textfield) {
    this.fontSetter = fontSetter;
    this.textfield = textfield;
}

Font font;

public void actionPerformed(ActionEvent e) {
    textfield.setFont(font.deriveFont(Font.BOLD));
}

}

class Italic implements ActionListener {

private final FontSetter fontSetter;
private final JTextField textfield;

Italic(FontSetter fontSetter, JTextField textfield) {
    this.fontSetter = fontSetter;
    this.textfield = textfield;
}

public void actionPerformed(ActionEvent e) {
    textfield.setText("");
}

}

class BoldItalic implements ActionListener {

private final FontSetter fontSetter;
private final JTextField textfield;

BoldItalic(FontSetter fontSetter, JTextField textfield) {
    this.fontSetter = fontSetter;
    this.textfield = textfield;
}

public void actionPerformed(ActionEvent e) {
    textfield.setText("");
}

}

class Times implements ActionListener {

private final FontSetter fontSetter;
private final JTextField textfield;

Times(FontSetter fontSetter, JTextField textfield) {
    this.fontSetter = fontSetter;
    this.textfield = textfield;
}

public void actionPerformed(ActionEvent e) {
    textfield.setText("Times");
}

}

class Helvetica implements ActionListener {

private final FontSetter fontSetter;
private final JTextField textfield;

Helvetica(FontSetter fontSetter, JTextField textfield) {
    this.fontSetter = fontSetter;
    this.textfield = textfield;
}

public void actionPerformed(ActionEvent e) {
    textfield.setText("Helvetica");
}

}

class Courier implements ActionListener {

private final FontSetter fontSetter;
private final JTextField textfield;

Courier(FontSetter fontSetter, JTextField textfield) {
    this.fontSetter = fontSetter;
    this.textfield = textfield;
}

public void actionPerformed(ActionEvent e) {
    textfield.setText("Courier");
}

}

I hope I have explained this clearly and would appreciate any help with my code, thanks.

p.s also my fontsetter class this doesnt have any function atm but it was how I originally intended to layout my action listeners

class FontSetter {

void setBold() {

}

void setItalic() {

}

void setBoldItalic() {

}

void setTimes() {

}

void setHelvetica() {

}

void setCourier() {

}
}
1
"copy the font name from the radio buttons to the textfield" The current code is very fragile in that it expects particular fonts to be installed. A windows machine might not have Helvetica installed. I just checked this Windows box, and although it has over 250 font families installed, not one of those is 'Helvetica'. To get the font families that really exist on that machine, see String[] fontFamilies = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); .. (Then I'd present them to the user in a JComboBox or JList.)Andrew Thompson

1 Answers

3
votes

You can define some variables in your FontSetter class to keep the current font name and style

Something like this

class FontSetter {

private final JTextField text;
private String fontName = "Times";
private boolean isBold = false;
private boolean isItalic = false;

FontSetter(JTextField text) {
    this.text = text;
}

void setBold(boolean flag) {
    isBold = flag;
    applyFontChanges();
}

void setItalic(boolean flag) {
    isItalic = flag;
    applyFontChanges();
}

void setFontName(String fontName) {
    this.fontName = fontName;
    applyFontChanges();
}

private void applyFontChanges(){
    Font font;
    int style;

    if(isBold && isItalic){
        style = Font.BOLD + Font.ITALIC;
    } else if(isBold){
        style = Font.BOLD;
    } else if(isItalic){
        style = Font.ITALIC;
    } else {
        style = Font.PLAIN;
    }

    font = new Font(fontName, style, 12);
    text.setFont(font );
}   
}

Then you can use it in your ActionListeners to change the font like this

fontSetter.setFontName("Courier");
textfield.setText("Courier");

And you can also change the style as follow

JCheckBox ch = (JCheckBox) e.getSource();
fontSetter.setBold(ch.isSelected());

--

Here is the complete code snippet