2012-03-05 38 views
2

我想要繪製圖形刷新/重新填充當用戶選擇JComboBox中的各種選項中的每一個。我在網上找到的例子都使用JLabels,這對圖像文件來說可能很好,但對於paintComponent生成的自定義圖形不起作用。從JComboBox控件重繪

我試着在下面的~60行代碼中滾動我自己的解決方案。我正在使用一個矩形的簡單示例來重新調整大小。如果您編譯並運行下面的代碼,您將看到當用戶從JComboBox中選擇不同的選項時,它不會重新繪製。此外,我故意沒有對displayConstraints做任何事情,因爲如果某人有更好的方法,我不想強​​加一個解決方案。我的目標是將JComboBox顯示在頂部的自己的行中,並將繪製的圖形顯示在第一行下面的更大的第二行中。第二行將吸收所有調整大小的更改,而第一行在調整JFrame大小時將保持大致相同的大小。通過從JComboBox中選擇不同的選項,用戶將能夠使繪製的矩形相對於JFrame的當前大小變得更小或更大。

任何人都可以告訴我如何解決下面的代碼,以便它實現我的上述目標?

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

問題在編輯之前是好的 – CodeMed 2012-03-05 23:48:08

+0

您可以恢復編輯,但現在看起來好了。 – trashgod 2012-03-06 02:18:24

回答

3

您不應該直接在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(); 
     } 
     }); 
    } 
} 
+0

+1快速回復。我將此標記爲答案,但仍然將組合框放在框架中間而不是頂部。稍後當我有更多時間來解決這個問題時,我會盡力解決這個問題。 – CodeMed 2012-03-05 23:53:48

+0

@CodeMed:把它放在最上面,使用不同的佈局管理器。我自己我會把JComboBox放在使用JPanel的FlowLayout中,並將JPanel放在另一個在BorderLayout.NORTH位置使用BorderLayout的JPanel(主面板)。 – 2012-03-06 00:06:59

0

關閉我的頭頂,沒有測試這是我想出了。使子類JPanel覆蓋paintComponent你在哪裏做你的圖形(如什麼氣墊船充滿鰻魚說)。添加到JFrame。現在,請加(而不是ItemListener)的ActionListener到您的組合框:

public void actionPerformed(ActionEvent evt) { 
    //do other stuff... 
    yourGraphicsPanel.repaint(); 
} 

yourGraphicsPanel是你一個實例的JPanel子類。

希望它有幫助! :)