【问题标题】:Why do I have to click my button twice for it to work?为什么我必须单击我的按钮两次才能使其工作?
【发布时间】:2021-12-30 03:34:08
【问题描述】:
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;
            } 
        }
    }
}

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

【问题讨论】:

  • 请更详细地描述您正在尝试做的事情、您期望发生的事情以及实际发生的事情。
  • 只是猜测,也许你想在你增加/减少actionPerformed 之后在你的check() 中调用你的index
  • 我不明白按钮如何“切换角色”,您应该让您的示例可编译。

标签: java swing jbutton


【解决方案1】:

您必须在状态更改之后调用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()(我在任何地方都找不到该类)并且必须添加一个 main 方法:

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

【讨论】:

  • 你的工作完美,但另一个人完全复制了我试图实现的目标,而且添加更多项目应用程序更加简单和容易,谢谢!
【解决方案2】:

我会创建一个专门的方法来选择特定的页面索引:

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()方法可以去掉,初始选择用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(..) 方法。

【讨论】:

  • 干得好,这正是我所需要的!
猜你喜欢
  • 2020-06-29
  • 2021-01-29
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
相关资源
最近更新 更多