简体   繁体   中英

Why do I have to click my button twice for it to work?

import javax.swing.*;
import javax.swing.border.Border;

import java.awt.*;
import java.awt.event.*;

public class LauncherFrame extends JFrame implements ActionListener{
    
    JPanel Title = new JPanel();
    JPanel LeftSide = new JPanel();
    JPanel RightSide = new JPanel();
    JPanel BottomFooter = new JPanel();
    JPanel MainCenter = new JPanel();
    JButton nextBTN = new JButton();
    JButton backBTN = new JButton();
    JLabel TitleLabel = new JLabel();
    JButton projectApp1 = new JButton();
    JButton projectApp2 = new JButton();
    JLabel appName = new JLabel();
    int radius;
    boolean Project1focused = true;
    boolean Project2focused = false;
    Border focusBorder = BorderFactory.createLineBorder(Color.green, 10);
    int index = 2;
    
    public LauncherFrame() {
        Image img = Toolkit.getDefaultToolkit().getImage("logo.png");
        ImageIcon img2 = new ImageIcon("logo.png");

        ImageIcon iconT = new ImageIcon("tic-tac-toe-image.jpg");
        Border border = BorderFactory.createLineBorder(new Color(0x89852A), 3);
        
        //Title Panel
        Title.setBackground(new Color(0xCD8028));
        Title.setPreferredSize(new Dimension(this.getWidth(), 100));
        Title.setBorder(border);
        
        //Title Label
        TitleLabel.setText("Banana Launcher");
        TitleLabel.setFont(new Font("Source Code Pro", Font.BOLD, 50));
        
        //Left Panel
        LeftSide.setBackground(new Color(0xA0A0A0));
        LeftSide.setPreferredSize(new Dimension(200, this.getHeight()));
        LeftSide.setLayout(null);
        LeftSide.add(backBTN);
        
        //Right Panel
        RightSide.setBackground(new Color(0xA0A0A0));
        RightSide.setPreferredSize(new Dimension(200, this.getHeight()));
        RightSide.setLayout(null);
        RightSide.add(nextBTN);
        
        //Footer
        BottomFooter.setBackground(new Color(0x504F31));
        BottomFooter.setPreferredSize(new Dimension(this.getWidth(), 75));
        
        //Project/App to open 1
        projectApp1.setIcon(iconT);
        projectApp1.setBackground(Color.GRAY);
        projectApp1.setBounds(325,150,255,255);
        projectApp1.setFocusable(false);
        projectApp1.setBorder(new RoundedBorder(10));
        projectApp1.addActionListener(this);

        //Project/App to open 2
        projectApp2.setIcon(img2);
        projectApp2.setBackground(Color.GRAY);
        projectApp2.setBounds(60,150,255,255);
        projectApp2.setFocusable(false);
        projectApp2.setBorder(new RoundedBorder(10));
        projectApp2.addActionListener(this);

        //label to tell us what app we're on
        appName.setText("hello");
        appName.setForeground(Color.BLACK);
        appName.setBounds(350,50,200,50);
        appName.setFont(new Font(null, Font.BOLD, 50));
        
        //Main Center
        MainCenter.setBackground(new Color(0xE9E8CE));
        MainCenter.setLayout(null);
        MainCenter.setFocusable(false);
        MainCenter.add(projectApp1);
        MainCenter.add(projectApp2);
        MainCenter.add(appName);
        
        //Right Panel Button
        nextBTN.setBackground(new Color(0x6F9023));
        nextBTN.setBounds(10,212,130,125);  
        nextBTN.setBorder(new RoundedBorder(10));
        nextBTN.setHorizontalAlignment(JButton.CENTER);
        nextBTN.setText("Next->");
        nextBTN.setFocusable(false);
        nextBTN.setFont(new Font("Ink Free", Font.BOLD, 25));
        nextBTN.setForeground(Color.BLACK);
        nextBTN.addActionListener(this);

        
        //Left Panel Button
        backBTN.setBackground(new Color(0x6F9023));
        backBTN.addActionListener(this);
        backBTN.setBounds(60,212,130,125);  
        backBTN.setBorder(new RoundedBorder(10));
        backBTN.setHorizontalAlignment(JButton.CENTER);
        backBTN.setText("<-Back");
        backBTN.setFocusable(false);
        backBTN.setFont(new Font("Ink Free", Font.BOLD, 25));
        backBTN.setForeground(Color.BLACK);
        
        check();
        
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.setSize(1300,850);
        this.setLayout(new BorderLayout());
        this.setLocationRelativeTo(null);
        this.setTitle("Launcher");
        
        Title.add(TitleLabel);
        this.setIconImage(img);
        this.add(Title, BorderLayout.NORTH);
        this.add(LeftSide, BorderLayout.WEST);
        this.add(RightSide, BorderLayout.EAST);
        this.add(BottomFooter, BorderLayout.SOUTH);
        this.add(MainCenter, BorderLayout.CENTER);
        this.setVisible(true);

    }
    public void check() {
        if(index==1) {
            projectApp2.setBorder(focusBorder);
            projectApp1.setBorder(null);
        } else if(index==2) {
            projectApp2.setBorder(null);
            projectApp1.setBorder(focusBorder);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {    
        if(e.getSource()==backBTN) {
            System.out.println("hello");
            check();
            if(index==2) {
                System.out.println("helloo");
                index--;
            }
        }
        if(e.getSource()==nextBTN) {
            check();
            System.out.println("hello");
            if(index==1) {
                System.out.println("helloo");
                index+=1;
            } 
        }
    }
}

Its just the last bit rlly, the index is stuffed up and is playing up i need some help. Also the next and back button can switch roles if you start clicking them oppositely which is really annoying and i have no idea how to fix this.

You must call check() after the state change, not before!

@Override
public void actionPerformed(ActionEvent e) {    
    if(e.getSource()==backBTN) {
        System.out.println("hello");
        if(index==2) {
            System.out.println("helloo");
            index--;
        }
    }
    if(e.getSource()==nextBTN) {
        System.out.println("hello");
        if(index==1) {
            System.out.println("helloo");
            index+=1;
        } 
    }
    check();
}

Note that to compile your code I had to remove those new RoundedBorder() (I could not find that class anywhere) and I had to add a main method:

public static void main(String[] args) {
    SwingUtilities.invokeLater(LauncherFrame::new);
}

I'd create a dedicated method to select a specific page index:

private void select(int i) {
    // make sure the index stays in the range 1..2 (increment when adding more elements).
    index = Math.max(1, Math.min(i, 2));
    System.out.println("selected index: " + index);

    if (index == 1) {
        projectApp2.setBorder(focusBorder);
        projectApp1.setBorder(null);
    }
    if (index == 2) {
        projectApp2.setBorder(null);
        projectApp1.setBorder(focusBorder);
    }
}

The check() method can be removed, and the initial selection is done with select(1) .

Your action listener method would then look like this:

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == backBTN) {
        select(index - 1);
    }
    if (e.getSource() == nextBTN) {
        select(index + 1);
    }
}

Implementing ActionListener and then dispatching events by source is an Antipattern in Swing. Instead, add a dedicated action listener to each component. As this is a @FunctionalInterface , you can express the action in a Lambda expression :

    nextBTN.addActionListener(actionEvent -> select(index + 1));
    ...
    backBTN.addActionListener(actionEvent -> select(index - 1));

The implements ActionListener and actionPerformed(..) method can then be removed.

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