Search code examples
javaswingcross-platformjtextfieldcompatibility

JTextField showing up on Mac but not on Windows


My brother requested me to make a simple GUI application which calculates his tax in a game he is playing. So I quickly assembled this code. I literally used 5 minutes, as I just wanted it to work quickly:

    public class MainGUI extends JFrame implements ActionListener  {

    private static final double EA_TAX = 0.05;

    private JButton btnProfit;
    private JTextField buyPrice;
    private JTextField sellPrice;
    private JTextField resultField;
    private JLabel buyLabel;
    private JLabel sellLabel;
    private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
    JPanel container;

    public MainGUI(){
        this.setSize(400,400);
        container = new JPanel();
        btnProfit = new JButton("Calculate");
        buyPrice = new JFormattedTextField(getIntFormatter(NUMBER_FORMAT));
        sellPrice = new JFormattedTextField(getIntFormatter(NUMBER_FORMAT));
        resultField = new JTextField();
        buyLabel = new JLabel("The price you intend to pay");
        sellLabel = new JLabel("Price you intend to sell the player for");
        resultField.setEditable(false);
        btnProfit.addActionListener(this);
        GridLayout gridLayout = new GridLayout(3,2);
        container.setLayout(gridLayout);
        container.add(buyLabel);
        container.add(sellLabel);
        container.add(buyPrice);
        container.add(sellPrice);
        container.add(btnProfit);
        container.add(resultField);

        container.setVisible(true);
        this.add(container);

        this.pack();
        this.setVisible(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

    private NumberFormatter getIntFormatter(NumberFormat NUMBER_FORMAT)    {
        NumberFormatter formatter = new NumberFormatter(NUMBER_FORMAT);
        formatter.setValueClass(Integer.class);
        formatter.setMinimum(0);
        formatter.setMaximum(Integer.MAX_VALUE);
        //formatter.setAllowsInvalid(false);
        formatter.setCommitsOnValidEdit(true);


        return formatter;
        }


    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == this.btnProfit){
            this.resultField.setText("" +determineProfitAfterTax(Integer.parseInt(buyPrice.getText().replace(",", "")), Integer.parseInt(sellPrice.getText().replace(",", ""))));
        }
    }

    private int determineProfitAfterTax(int buyPrice, int sellPrice){
        return (int) (sellPrice * (1.00 - EA_TAX)) - buyPrice;
    }
}

in the Java class MainApplication.java i instantiate the JFrame:

public class MainApplication {

    public static void main(String args[]){
        new MainGUI();
    }
}

All of the text fields show up except the resultField JTextField, which is the one that holds the result. Any particular reason this works on Mac and not on windows? All input is appreciated.


Solution

  • The problem was solved by constructing the GUI Swing GUI options on the event dispatch thread (strongly suggested by the user @trashgod. To clarify, instead of doing this:

    public class MainApplication {
    
        public static void main(String args[]){
            new MainGUI();
        }
    }
    

    do this:

    public class MainApplication {
    
        public static void main(String args[]){
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new MainGUI();
                }
            });
        }
    }
    

    Please always try and use the second approach, even though it may seem that your program works when using the first approach. Using the first approach produces very weird side effects.