2012-03-05 11 views
2

ユーザーがJComboBox内のさまざまなオプションのそれぞれを選択したときに、プロットされたグラフィックをリフレッシュ/再作成するようにしようとしています。私がWeb上で見つけた例はすべてJLabelsを使用していますが、これはイメージファイルでは問題ありませんが、paintComponentで生成されたカスタムグラフィックスでは機能しません。JComboBoxコントロールからの再描画

私は自分のソリューションを〜60行のコードでロールバックしようとしました。私は、サイズを変更するための矩形の簡単な例を使用しています。以下のコードをコンパイルして実行すると、ユーザーがJComboBoxから別のオプションを選択したときに再描画されないことがわかります。また、誰かがより良いアプローチをしている場合、私は解決策を課したくないので、私は意図的にdisplayConstraintsで何もしていません。私の目標は、JComboBoxを一番上の行に表示し、プロットされたグラフを最初の行の下のはるかに大きな第2行で表示することです。 2番目の行はすべてのサイズ変更を吸収しますが、最初の行は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

+0

編集を元に戻すことはできますが、今はOKです。 – trashgod

答えて

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

+0

@CodeMed:上部に配置するには、別のレイアウトマネージャを使用します。私はJPanelを使用してFlowLayoutにJComboBoxを配置し、BorderLayout.NORTH位置でBorderLayoutを使用する別のJPanel(メインパネル)にJPanelを配置します。 –

0

、これは私が思いついたものですテストなし。 Hovercraft Full Of Eelsのように、グラフィックを作成するpaintComponentを上書きするサブクラスJPanelを作成します。 JFrameに追加します。今すぐあなたのコンボボックスに(代わりにItemListenerの)ActionListenerを追加します

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

yourGraphicsPanelはあなたのJPanelのサブクラスのインスタンスです。

希望すると助かります! :)