【问题标题】:Calculator: Buttons ONLY show up when mouse hovers over them in Test JFrame class计算器:仅当鼠标悬停在 Test JFrame 类中的按钮上时才会显示按钮
【发布时间】:2013-12-25 08:14:51
【问题描述】:

我很着急,所以 idc 关于副本。我仍在努力学习 Java 和术语,直到本学期结束。我用了一个模板。我正在使用背景图片(“面板”),这会使一切变得复杂。

基本上,这些按钮只有在我将鼠标悬停在它们上方时才会显示。很明显,它与 JPanel 有一些关系。

我排除了您可能会要求的代码,希望这次有人能帮助我,因为我的按钮与我在查看其他推荐帖子时看到的不同。

另外,我可以将 JFrame 设为固定大小(Test 类代码中的大小)吗?

代码可能是多余的,但我只是想让一切正常。请记住,我是 Java 新手。

测试类:

public class TestCalculator {    
    public static void main(String[] args) {
        JFrame frame = new JFrame(TestCalculator.class.getSimpleName());
        ImagePanel panel = new ImagePanel(new ImageIcon("01_Crane_AGweb.jpg").getImage());
        SimpleArithmeticCalculator calc = new SimpleArithmeticCalculator();        
        calc.SetColors(null , Color.white , new Color(72,61,139));
        calc.setVisible(true);
        calc.setOpaque(false);
        panel.setVisible(true);
        panel.setOpaque(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        calc.add(panel);
        frame.add(panel);
        frame.add(calc);       
        frame.getContentPane().add(calc);   
        frame.setPreferredSize(new Dimension(358,379));
        frame.setMinimumSize(new Dimension(358,379));
        frame.setVisible(true);
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    }
}
class ImagePanel extends JPanel {
    private Image img;
    public ImagePanel(String img) {
    this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
    this.img = img;
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
    this.setPreferredSize(new Dimension(size));
    this.setMinimumSize(new Dimension(size));
    this.setMaximumSize(new Dimension(size));
    this.setSize(new Dimension(size));
    this.setLayout(null);
}
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(img, 0, 0, this.getWidth(),this.getHeight(),this);
}
}

主要:

    public class SimpleArithmeticCalculator extends JPanel implements ActionListener {

         //BUTTONSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS !
         ...
         // jpanels, buttons, font, values, etc

        public SimpleArithmeticCalculator() {

          super();

      //I THINK this is the problem:  

      buttonPanel.setForeground(null);
      textPanel.setForeground(null);
      calcPanel.setForeground(null);

      textPanel.setLayout(new GridLayout(0,1,0,0));
      buttonPanel.setLayout(new GridLayout(0 , 5 , 5 , 5));

      displayText = new JTextField("" , 20);
      displayText.setHorizontalAlignment(JTextField.RIGHT);
      displayText.setFont(font);
      displayText.setEditable(false);

      textPanel.add(displayText);
      buttons = new JButton[NUM_BUTTONS];

      for (int i = 0 ; i < NUM_BUTTONS ; ++i) {

          buttons[i] = new JButton("" + buttonTexts[i]);
          buttons[i].setMnemonic(buttonKeys[i]);
          buttons[i].setFont(font);
          buttons[i].setMinimumSize(new Dimension(50,50));
          buttons[i].setActionCommand("" + buttonTexts[i]);
          buttons[i].addActionListener(this);
          buttonPanel.add(buttons[i]);
      }

      buttons[BTN_POWER].setText("^");
      buttons[BTN_PERCENT].setText("%");

      buttonPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
      textPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
      calcPanel.setLayout(new BorderLayout());
      calcPanel.add(textPanel , BorderLayout.NORTH);
      calcPanel.add(buttonPanel , BorderLayout.CENTER);
      add(calcPanel);

      setMinimumSize(new Dimension(358,379));

      setPreferredSize(new Dimension(359,381));

       for (int i = 0 ; i < NUM_BUTTONS ; ++i) {
           buttons[i].setMaximumSize(buttons[i].getSize());
       }

   }

     public void SetColors(Color bg , Color textbg , Color textcolor) {

       calcPanel.setBackground(bg);
       calcPanel.setVisible(true);
       calcPanel.setOpaque(false);
       buttonPanel.setBackground(bg);
       buttonPanel.setVisible(true);
       buttonPanel.setOpaque(false);
       textPanel.setBackground(bg);
       textPanel.setOpaque(true);
       textPanel.setVisible(true);
       displayText.setBackground(textbg);
       displayText.setForeground(textcolor);

       for (int i = 0 ; i < NUM_BUTTONS ; ++i) { 
            buttons[i].setForeground(textcolor);
       }

     }

     //ACTION PERFORMED STUFF & OPERATIONS, BLAH

     public boolean isOpCharacter(char c) {

          return ((c == buttonTexts[BTN_MULT]) ||
                  (c == buttonTexts[BTN_DIV]) ||
                  (c == buttonTexts[BTN_PLUS]) ||
                  (c == buttonTexts[BTN_MINUS]) ||
                  (c == buttonTexts[BTN_POWER]) ||
                  (c == buttonTexts[BTN_PERCENT]));
     }

     public boolean isNumericCharacter(char c) {

      return ((c == buttonTexts[BTN_ZERO]) ||
        (c == buttonTexts[BTN_ONE]) ||
        (c == buttonTexts[BTN_TWO]) ||
        (c == buttonTexts[BTN_THREE]) ||
        (c == buttonTexts[BTN_FOUR]) ||
        (c == buttonTexts[BTN_FIVE]) ||
        (c == buttonTexts[BTN_SIX]) ||
        (c == buttonTexts[BTN_SEVEN]) ||
        (c == buttonTexts[BTN_EIGHT]) ||
        (c == buttonTexts[BTN_NINE]) ||
        (c == buttonTexts[BTN_DECIMAL]));

     }

     public boolean isNonZeroNumber(char c) {

      return (c == buttonTexts[BTN_ONE] ||
        c == buttonTexts[BTN_TWO] ||
        c == buttonTexts[BTN_THREE] ||
        c == buttonTexts[BTN_FOUR] ||
        c == buttonTexts[BTN_FIVE] ||
        c == buttonTexts[BTN_SIX] ||
        c == buttonTexts[BTN_SEVEN] ||
        c == buttonTexts[BTN_EIGHT] ||
        c == buttonTexts[BTN_NINE]);

     }

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

【问题讨论】:

  • 如果您只向我们展示您的一半代码,任何人都很难重现您的问题并找出发生了什么。有没有机会全部粘贴进去?
  • 您需要发布相关的内容...您发布了 25 行 private static final int 声明...而这些变量甚至都没有在此代码的任何地方使用。该部分可能可以安全地省略...您的问题是按钮可见性...因此找到与该部分相关的所有代码位,发布它们,并省略其他所有内容。
  • @nhgrif 我不同意你的看法。如果我们要帮助这个人找到她的问题,我们应该有她的整个计划。在我看来,每次有人发布一个问题,包括一半的代码,并说“错误在哪里?”,错误结果是他们没有发布的一半。让回答问题的人来判断什么是相关的,什么是不相关的。
  • 我发布了按钮,但有人说它太多了。大卫明白。好的,所以,除非我将鼠标悬停在按钮上,否则按钮不会显示。然后,我将再次发布按钮。它编译,所以我测试了它。它只是按钮,恰好是代码中最长的部分。
  • @nhgrif 如果每个在 Stack Overflow 上提出问题的人都已经缩小了错误范围并构建了 SSCCE,那就太好了。但是这个人已经说过她是 Java 新手。也许她只是还没有你的分析和解决问题的能力。所以我们可以为她制造困难,或者我们可以尝试帮助她。我试图帮助她,但是当我在复制/粘贴代码并试图让它编译时(它没有),一个比我聪明的人想出了正确的答案。

标签: java jpanel jbutton calculator


【解决方案1】:

这是你的问题 您已经在面板和框架之前显示的面板和面板之前创建并显示了 calc。

    calc.setVisible(true); <------------Visible first
    calc.setOpaque(false);
    panel.setVisible(true); <----Second
    panel.setOpaque(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    calc.add(panel);
    frame.add(panel);
    frame.add(calc);       
    frame.getContentPane().add(calc);   
    frame.setPreferredSize(new Dimension(358,379));
    frame.setMinimumSize(new Dimension(358,379));
    frame.setVisible(true); <---Third

然而,计算在面板上,面板在框架上。你把它们颠倒了。首先创建框架。然后创建面板并将面板放在框架内。然后进行计算并将其放在面板内。然后显示框架。显示面板。显示计算。你只是顺序错了。我已经做过很多次了。

【讨论】:

  • “calc”和“panel”变量都是 JPanel 的实例。 Swing 组件默认是可见的(JFrame、JDialog、JWindow 等顶级容器除外),因此这些语句没有做任何事情,也不是问题的原因。
  • 天啊,哇!!非常感谢!我简化了它并且它有效!非常感谢您对我的耐心等待!
【解决方案2】:

无需创建图像面板类。您可以使用 JLabel 来显示 ImageIcon。

    frame.pack(); // this is the problem, invoke after all the components have been added
    calc.add(panel);
    frame.add(panel);
    frame.add(calc);       
    frame.getContentPane().add(calc);   
    frame.setPreferredSize(new Dimension(358,379)); 
    frame.setMinimumSize(new Dimension(358,379));
    frame.setVisible(true);

如果我不得不做出一个疯狂的猜测,我会说问题是你在将所有组件添加到框架之前使用 frame.pack()。

创建框架的基本代码应该是:

//  Create all the panel and add all the components to the panels

JPanel panel = new JPanel();
panel.add(..);

//  Create the frame and add all the panels to the frame.

JFrame frame = new JFrame(...);
frame.add( panel ;
frame.pack();
frame.setVisible(true);

更新:

另一个问题可能与以下代码有关:

frame.add(panel);
frame.add(calc);

默认情况下,框架使用 BorderLayout。当您将组件添加到框架时,默认情况下它们会添加到 CENTER,问题是一次只能将单个组件添加到 CENTER。看起来您正在尝试使用背景图像。如果是这种情况,那么正如我之前建议的那样,您可以使用 JLabel 作为背景。你的代码应该是这样的:

JLabel background = new JLabel( new ImageIcon(...) );
background.setLayout( new BorderLayout() );

SimpleArithmeticCalculator calc = new SimpleArithmeticCalculator();  
background.add( calc );

JFrame frame = new JFrame(...);
frame.add( background );
frame.pack();
frame.setVisible( true );

现在计算器将显示在背景之上。或者,如果您仍然想使用 ImagePanel,那么概念仍然相同,您将计算器添加到图像面板,将图像面板添加到框架中。

【讨论】:

  • 我重新订购了面板和框架,一切正常,非常感谢您对我的耐心!我的代码到处都是。感谢您帮我简化它!
  • 我收到此错误:BorderLayout 无法解析为类型。我将“面板”更改为“背景”并导入 java.awt 并编译,但图像没有显示。
  • 我不知道你在做什么。我的建议和以前一样。创建一个简单的 JFrame,它显示带有 ImageIcon 的 JLabel。大约需要 10-15 行代码。让这个简单的例子起作用。然后,当您了解如何执行此操作时,下一步将其添加到背景图像中。
  • 使用 ImagePanel 可以正常工作,但我尊重您的建议,所以我将坚持使用 ImagePanel。
猜你喜欢
  • 2014-06-30
  • 2022-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 2017-08-15
  • 2017-12-15
相关资源
最近更新 更多