2012-11-20 32 views
0

這是我得到的。跟蹤Swing組件的正確方法是什麼?

在這段代碼中,我創建了一個包含7個滑塊和一個組合框的面板。

public JPanel createOscPanel(final Osc o) 
{ 
     //create a panel of 2 rows, 4 columns*/ 
    JPanel panel = gc.createComponentPanel(o.NAME, 2, 4);     

    /*set up combobox panel*/ 
    JPanel cbPanel = new JPanel(); 
    cbPanel.setLayout(new BoxLayout(cbPanel, BoxLayout.Y_AXIS)); 

     /*label*/ 
    JPanel lbPanel = new JPanel(); 
    lbPanel.setLayout(new BoxLayout(lbPanel, BoxLayout.X_AXIS)); 
    lbPanel.setAlignmentY(LEFT_ALIGNMENT); 
    JLabel cbLabel = new JLabel("Wave Type:"); 
    lbPanel.add(cbLabel); 
    cbPanel.add(lbPanel); 

     /*combobox*/ 
    final String[] comboItems = {"Sine", "Custom", "FSaw", "FSquare"}; 
    JComboBox cb = new JComboBox(comboItems); 
    cb.setMaximumSize(new Dimension (100, 20)); 

    cbPanel.add(cb); 

    /*add sliders*/ 
    panel.add(gc.createSliderPanel(o.getAmp(), DEFAULT_SLIDER_GRAINS)); 
    panel.add(gc.createSliderPanel(o.getFreq(), DEFAULT_SLIDER_GRAINS)); 
    panel.add(gc.createSliderPanel(o.getPhase(), DEFAULT_SLIDER_GRAINS)); 
    panel.add(cbPanel); 
    panel.add(gc.createSliderPanel(o.getWidth(), DEFAULT_SLIDER_GRAINS)); 
    panel.add(gc.createSliderPanel(o.getSlope(), DEFAULT_SLIDER_GRAINS)); 
    panel.add(gc.createSliderPanel(o.getCurve(), DEFAULT_SLIDER_GRAINS)); 
    panel.add(gc.createSliderPanel(o.getFourier(), (o.getFourier().MAX - o.getFourier().MIN))); 

    final Runnable disableCustomSliders = new Runnable() /*this is how do a method-in-method in Java*/ 
    { 
     public void run() 
     { 
        //I need to disable sliders here.      

     } 
    }; 

    final Runnable enableCustomSliders = new Runnable() /*this is how do a method-in-method in Java*/ 
    { 
     public void run() 
     { 

       //I need to enable sliders here. 
     } 
    }; 

    cb.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      JComboBox cb = (JComboBox)e.getSource(); 
      int value = cb.getSelectedIndex(); 

      switch(value) 
      { 
      case 0: {o.setWaveShape(Osc.WaveShape.SINE); disableCustomSliders.run();} break; 
      case 1: {o.setWaveShape(Osc.WaveShape.CUSTOM); enableCustomSliders.run();} break; 
      case 2: {o.setWaveShape(Osc.WaveShape.FSAW); disableCustomSliders.run();} break; 
      case 3: {o.setWaveShape(Osc.WaveShape.FSQUARE);disableCustomSliders.run();} break; 

      } 

      refresh(); 
     } 
    }); 

    return panel; 

} 

當您選擇組合框的正弦,FSAW,FSquare項目,你需要禁用曲線,寬度和斜率滑塊,當您選擇自定義項目,則需要重新啓用它們。

這裏是createSliderPanel的代碼。

public JPanel createSliderPanel(
     final Parameter parameter, 
     final int grains) 
{  
    /*create and assign components*/ 
    final JPanel panel = new JPanel(); 
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 
    panel.setBorder(BorderFactory.createRaisedBevelBorder()); 

    final JLabel label = new JLabel(parameter.NAME); 
    final JLabel valueLabel = new JLabel(); 

    /*set up slider*/ 
    int curr = valueToSlider(parameter.MIN.doubleValue(), parameter.MAX.doubleValue(), 
      parameter.getValue().doubleValue(), parameter.SCALETYPE, parameter.Q, grains); 
    final JSlider slider = new JSlider(JSlider.VERTICAL, 0, grains, curr); 

    slider.setPreferredSize(new Dimension(SLIDER_WIDTH, SLIDER_HEIGHT)); 

    slider.setAlignmentX(Component.LEFT_ALIGNMENT); 



    panel.add(valueLabel); 
    panel.add(slider); 
    panel.add(label); 

    /*slider move event*/ 
    slider.addChangeListener(new ChangeListener() { 
     /* (non-Javadoc) 
     * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) 
     */ 
     public void stateChanged(ChangeEvent event) { 

      double value = sliderToValue(parameter.MIN.doubleValue(), parameter.MAX.doubleValue(),slider.getValue(), parameter.SCALETYPE, parameter.Q, grains); 

      updateSliderLabel(parameter, valueLabel, parameter.getValue()); 

      /*set the parameter value*/ 
      if (parameter.CLASSTYPE.equals(Double.class)) 
        parameter.setValue(value); 
      else if (parameter.CLASSTYPE.equals((Integer.class))) 
        parameter.setValue((int)value); 

      gui.refresh(); 
     } 


    }); 

    /*need to reset the valueLabel to it's correct format*/ 
    updateSliderLabel(parameter, valueLabel, parameter.getValue()); 

    return panel; 
} 

所以問題是 - 我如何引用這些滑塊以便對它們執行.setEnabled(false)?

我能想到的直接和合理簡單的解決方案是重構createSliderPanel,以便您傳遞父面板,並將滑塊面板添加​​到方法內的父級,然後返回滑塊。

是否有一個更好的概念,堅持OO和MVC?

最後一個問題:堆棧溢出的有效性和禮節 - 是發佈這些代碼很好的禮貌和有效的大塊?還是會讓問題更難回答?

+2

問題歸結爲「如何獲得對象的引用」,並且有許多可能的解決方案,包括將它們放置在諸如'HashMap '或ArrayList或數組等的Map中,或者任何系統最有效的方法爲你。關於SO的禮儀,大多數人都非常感謝您發佈一個[sscce](http://sscce.org),一小部分可編譯和可運行的代碼,其中不包含與您的問題無關的代碼,並在程序中顯示問題的實質我們可以保持不變。 –

+2

*「是發佈這些大塊的代碼好禮貌和有效的?」*爲了更好地幫助更快,發佈[SSCCE](http://sscce.org/)。但注意1)這兩個代碼片段不是我認爲是「大」的。 2)即使這麼說,這看起來像是如果你可以使用一個控件,它應該很容易一打 - 所以只包括1. –

回答

2

我個人會創建一個自定義組件,而不是從頭開始構建滑塊面板。這將使您有機會提供可用於更改整個組件的啓用狀態的「控制」方法,並提供可用於在需要時檢索滑塊值的獲取器和設置器。

+0

我喜歡這個建議。 所以'公共類SliderPanel'應該擴展'Component'或'JPanel'嗎? – dwjohnston

+1

堅持使用Swing組件(更簡單),我會使用'JPanel'來處理不透明度 – MadProgrammer

相關問題