Java 从JComboBox控件重新绘制
当用户在JComboBox中选择各种选项时,我试图让绘制的图形刷新/重新填充。我在web上找到的示例都使用JLabel,这对于图像文件可能很好,但对于paintComponent生成的自定义图形不起作用 我试着在下面约60行代码中推出我自己的解决方案。我正在使用一个简单的例子来重新调整矩形的大小。如果编译并运行下面的代码,您将看到当用户从JComboBox中选择不同的选项时,它不会重新绘制。此外,我还特意没有对displayConstraints做任何事情,因为如果有人有更好的方法,我不想强加一个解决方案。我的目标是让JComboBox显示在顶部自己的一行中,并在第一行下面更大的第二行中完成绘制的图形。第二行将吸收所有调整大小的更改,而在调整JFrame的大小时,第一行将保持大致相同的大小。通过从JComboBox中选择不同的选项,用户将能够使绘制的矩形相对于JFrame的当前大小变小或变大 有谁能告诉我如何修复下面的代码,从而实现我上面提到的目标Java 从JComboBox控件重新绘制,java,swing,graphics,plot,jcombobox,Java,Swing,Graphics,Plot,Jcombobox,当用户在JComboBox中选择各种选项时,我试图让绘制的图形刷新/重新填充。我在web上找到的示例都使用JLabel,这对于图像文件可能很好,但对于paintComponent生成的自定义图形不起作用 我试着在下面约60行代码中推出我自己的解决方案。我正在使用一个简单的例子来重新调整矩形的大小。如果编译并运行下面的代码,您将看到当用户从JComboBox中选择不同的选项时,它不会重新绘制。此外,我还特意没有对displayConstraints做任何事情,因为如果有人有更好的方法,我不想强加一
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
public class ComboBox extends JFrame implements ItemListener {
final String[] sizes = { "10%", "20%", "33%" };
JComboBox combobox = new JComboBox(sizes);
int selectedIndex;
public ComboBox() {
setLayout(new GridBagLayout());
combobox.setSelectedIndex(-1);
combobox.addItemListener(this);
GridBagConstraints comboBoxConstraints = new GridBagConstraints();
comboBoxConstraints.gridx = 0;
comboBoxConstraints.gridy = 0;
comboBoxConstraints.gridwidth = 1;
comboBoxConstraints.gridheight = 1;
comboBoxConstraints.fill = GridBagConstraints.NONE;
add(combobox,comboBoxConstraints);//This should be placed at top, in middle.
GridBagConstraints displayConstraints = new GridBagConstraints();
displayConstraints.gridx = 0;
displayConstraints.gridy = 1;
displayConstraints.gridwidth = 1;
displayConstraints.gridheight = 1;
displayConstraints.fill = GridBagConstraints.BOTH;
//I am aware that nothing is done with displayConstraints.
//I just want to indicate that the rectangle should go below the combobox,
//and that the rectangle should resize while the combobox should not.
//Other suggested approaches are welcome.
setSize(300, 300);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {new ComboBox();}
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
JComboBox combo = (JComboBox) e.getSource();
selectedIndex = combo.getSelectedIndex();
System.out.println("selectedIndex is: "+selectedIndex);
repaint();
}
}
protected void paintComponent(Graphics g){
int scaleFactor = 1;
if(selectedIndex==0){scaleFactor = 10;}
if(selectedIndex==1){scaleFactor = 5;}
if(selectedIndex==2){scaleFactor = 3;}
if(selectedIndex!=-1){
int xStart = (getWidth()/2)-(getWidth()/scaleFactor);
int yStart = (getHeight()/2)-(getHeight()/scaleFactor);
g.drawRect(xStart, yStart, (getWidth()/scaleFactor), (getHeight()/scaleFactor));
}
}
}
您不应该直接在JFrame中绘制,即使这样,JFrame也没有paintComponent方法。使用
@Override
注释自己查看。相反,在JPanel或JComponent中绘制,在paintComponent中绘制,并确保使用覆盖注释正确覆盖了该方法
例如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ComboBoxTest extends JPanel implements ItemListener {
private static final int PREF_W = 300;
private static final int PREF_H = PREF_W;
final String[] sizes = { "10%", "20%", "33%" };
JComboBox combobox = new JComboBox(sizes);
int selectedIndex;
private double scaleFactor = 1;
public ComboBoxTest() {
setLayout(new GridBagLayout());
combobox.setSelectedIndex(-1);
combobox.addItemListener(this);
GridBagConstraints comboBoxConstraints = new GridBagConstraints();
comboBoxConstraints.gridx = 0;
comboBoxConstraints.gridy = 0;
comboBoxConstraints.gridwidth = 1;
comboBoxConstraints.gridheight = 1;
comboBoxConstraints.fill = GridBagConstraints.NONE;
add(combobox, comboBoxConstraints);// This should be placed at top, in
// middle.
GridBagConstraints displayConstraints = new GridBagConstraints();
displayConstraints.gridx = 0;
displayConstraints.gridy = 1;
displayConstraints.gridwidth = 1;
displayConstraints.gridheight = 1;
displayConstraints.fill = GridBagConstraints.BOTH;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
JComboBox combo = (JComboBox) e.getSource();
selectedIndex = combo.getSelectedIndex();
System.out.println("selectedIndex is: " + selectedIndex);
if (selectedIndex == -1) {
return;
}
String selectedItem = combo.getSelectedItem().toString().trim();
selectedItem = selectedItem.replace("%", "");
scaleFactor = Double.parseDouble(selectedItem) / 100.0;
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int xStart = (getWidth() / 2) - (int)(getWidth() * scaleFactor);
int yStart = (getHeight() / 2) - (int)(getHeight() * scaleFactor);
g.drawRect(xStart, yStart, (int)(getWidth() * scaleFactor),
(int)(getHeight() * scaleFactor));
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ComboBoxTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ComboBoxTest());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
在我脑子里,没有测试,这就是我想到的。制作一个子类
JPanel
,覆盖paintComponent
,你可以在那里绘制图形(就像气垫船上满是鳗鱼说的那样)。添加到JFrame。现在,在组合框中添加一个ActionListener
(而不是ItemListener
):
public void actionPerformed(ActionEvent evt) {
//do other stuff...
yourGraphicsPanel.repaint();
}
yourGraphicsPanel
是您的JPanel子类的一个实例
希望有帮助!:) 在编辑之前,问题还可以。您可以恢复编辑,但现在看起来还可以。快速回复+1。我将此标记为答案,但它仍然将组合框放置在帧的中间而不是顶部。我将在以后有更多时间处理此问题时尝试修复该细节。@CodeMed:若要将其置于顶部,请使用其他布局管理器。我自己会使用JPanel将JComboBox放在FlowLayout中,并将该JPanel放在另一个JPanel(主面板)中,该JPanel使用BorderLayout.NORTH位置的BorderLayout。