为什么我必须点击我的按钮两次才能工作?

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;
            } 
        }
    }
}

真的只是最后一点,索引已满,正在播放我需要一些帮助。 如果您开始相反地点击它们,下一步和后退按钮也可以切换角色,这真的很烦人,我不知道如何解决这个问题。

我会为 select 特定页面索引创建一个专用方法:

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);
    }
}

可以去掉check()方法,初始selection用select(1)完成。

您的动作侦听器方法将如下所示:

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

实施 ActionListener 然后按源分派事件是 Swing 中的 反模式。相反,为每个组件添加一个专用的动作侦听器。由于这是一个 @FunctionalInterface,您可以在 Lambda 表达式:

中表达操作
    nextBTN.addActionListener(actionEvent -> select(index + 1));
    ...
    backBTN.addActionListener(actionEvent -> select(index - 1));

然后可以删除 implements ActionListeneractionPerformed(..) 方法。

您必须在 check() 状态更改之后调用 ,而不是之前!

@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();
}

请注意,为了编译您的代码,我必须删除那些 new RoundedBorder()(我在任何地方都找不到 class)并且我必须添加一个主要方法:

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