问题
I'm rushing, so idc about the duplicate. I'm still trying to learn Java and the terms, until the end of this semester, that is. I used a template. I'm using a background image ("panel"), which complicates everything.
Basically, the buttons only show up when I hover over them. It has something to do w/ the JPanels, clearly.
I excluded code that you'd probably ask for so that hopefully, someone helps me this time because my buttons are not like the ones I've seen when looking on other recommended posts.
Also, can I make the JFrame a fixed size (the size in the Test class code)?
Code may be redundant, but I'm just trying to make everything work. Keep in mind, I'm NEW to Java.
TEST CLASS:
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);
}
}
MAIN:
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) { }
}
回答1:
There is no need to create an image panel class. You can use a JLabel to display an 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);
If I had to make a wild guess I would say the problem is that you are using frame.pack() BEFORE you add all the components to the frame.
The basic code for creating a frame should be:
// 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);
Update:
Another problem could be with the following code:
frame.add(panel);
frame.add(calc);
By default a frame uses a BorderLayout. When you add components to the frame they are added to the CENTER by default and the problem is only a single component can be added to the CENTER at one time. It looks like you are trying to have a background image. If this is the case then as I suggested earlier you can use a JLabel for the background. Your code should be something like:
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 );
Now the calculator will be displayed on top of the background. Or if you still want to use your ImagePanel then the concept is still the same, you add the calculator to the image panel and the image panel to the frame.
回答2:
Here is your problem You have calc created and shown before the panel and the panel shown before the frame.
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
Yet the calc goes on the panel and the panel goes on the frame. You have them reversed. Create the frame first. Then create the panel and put the panel inside the frame. then make the calc and put it inside the panel. Then show frame. show panel. show calc. You just have the order wrong. I've done this many times.
来源:https://stackoverflow.com/questions/20449977/calculator-buttons-only-show-up-when-mouse-hovers-over-them-in-test-jframe-clas