2013-09-26 38 views
0

我目前遇到了我的最新项目的问题。 我是个初学者,所以请记住这一点:dItemListener复选框按预期工作

我想要什么我的项目做的是改变一些文字的,如果复选框被选中的字体,并使其返回到正常的,如果它被取消选中。

我已经设法实现了。

但是,有多行复选框。如果选择了2,我取消选择其中一个,文本将变回正常状态。只要列中的复选框仍处于选中状态,我不希望文本变为正常。

我该怎么做? =(

希望你可以帮我!

import java.awt.Color; 

public class WindowBuilderTest extends JFrame 
{ 

private JPanel contentPane; 

//Launch the application. 
public static void main(final String[] args) 
{ 
    EventQueue.invokeLater(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      try 
      { 
       final WindowBuilderTest frame = new WindowBuilderTest(); 
       frame.setVisible(true); 
      } 
      catch (final Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

// Creating Frame 
public WindowBuilderTest() 
{ 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 1280, 720); 
    this.contentPane = new JPanel(); 
    this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(this.contentPane); 
    this.contentPane.setLayout(null); 

    // Create Font 
    final Font headfont = new Font("Serif", Font.PLAIN, 15); 
    final Font headfontRed = new Font("Serif", Font.PLAIN, 15); 

    // Role Headlines 
    final JTextArea txtTop = new JTextArea(); 
    txtTop.setEditable(false); 
    txtTop.setText("TOP"); 
    txtTop.setBounds(180, 95, 32, 23); 
    this.contentPane.add(txtTop); 

    final JTextArea txtMid = new JTextArea(); 
    txtMid.setEditable(false); 
    txtMid.setText("MID"); 
    txtMid.setBounds(252, 95, 32, 23); 
    this.contentPane.add(txtMid); 

    final JTextArea txtJng = new JTextArea(); 
    txtJng.setEditable(false); 
    txtJng.setText("JNG"); 
    txtJng.setBounds(320, 95, 32, 23); 
    this.contentPane.add(txtJng); 

    final JTextArea txtAdc = new JTextArea(); 
    txtAdc.setEditable(false); 
    txtAdc.setText("ADC"); 
    txtAdc.setBounds(389, 95, 32, 23); 
    this.contentPane.add(txtAdc); 

    final JTextArea txtSup = new JTextArea(); 
    txtSup.setEditable(false); 
    txtSup.setText("SUP"); 
    txtSup.setBounds(453, 95, 32, 23); 
    this.contentPane.add(txtSup); 

    // Checkbox 1st row 
    addCheckBox(183, 143, 23, 23, txtTop); 
    addCheckBox(255, 143, 23, 23, txtMid); 
    addCheckBox(322, 143, 23, 23, txtJng); 
    addCheckBox(393, 143, 23, 23, txtAdc); 
    addCheckBox(457, 143, 23, 23, txtSup); 

    // Checkbox 2nd row 
    addCheckBox(183, 200, 23, 23, txtTop); 
    addCheckBox(255, 200, 23, 23, txtMid); 
    addCheckBox(322, 200, 23, 23, txtJng); 
    addCheckBox(393, 200, 23, 23, txtAdc); 
    addCheckBox(457, 200, 23, 23, txtSup); 

    // Checkbox 3nd row 
    addCheckBox(183, 257, 23, 23, txtTop); 
    addCheckBox(255, 257, 23, 23, txtMid); 
    addCheckBox(322, 257, 23, 23, txtJng); 
    addCheckBox(393, 257, 23, 23, txtAdc); 
    addCheckBox(457, 257, 23, 23, txtSup); 
} 


private void addCheckBox(final int x, final int y, final int width, final int height, final JTextArea txtTop) 
{ 
    final JCheckBox checkBox = new JCheckBox(); 
    checkBox.setBounds(x, y, width, height); 
    checkBox.addItemListener(new FontChanger(txtTop)); 
    this.contentPane.add(checkBox); 
} 

class FontChanger implements ItemListener 
{ 
    private JTextArea textArea; 

    public FontChanger(final JTextArea textArea) 
    { 
     this.textArea = textArea; 
    } 

    @Override 
    public void itemStateChanged(final ItemEvent e) 
    { 
     if (e.getStateChange() == ItemEvent.SELECTED) 
     { 
      final Font boldFont = this.textArea.getFont().deriveFont(Font.BOLD); 
      this.textArea.setForeground(Color.RED); 
      this.textArea.setFont(boldFont); 
     } 
     else 
     { 
      final Font boldFont = this.textArea.getFont().deriveFont(Font.PLAIN); 
      this.textArea.setForeground(Color.BLACK); 
      this.textArea.setFont(boldFont); 
     } 
    } 
} 

}

回答

0

有实现你想要什么尝试做的,但我相信这个问题是比较概念的几种方式。每个复选框要添加到您的面板有* 自己 * FontChanger。每个那些FontChangers的不知道其他FontChangers或复选框对这一问题。你可以做什么,而不是,是有一个单一FontChanger添加到所有的复选框然后有一个letti的方式你的单个FontChanger知道itemStateChanged()方法中每个复选框的状态。通过这种方式,您可以查看是否/选择了多少/哪个复选框并对其执行操作。

编辑:这是一个完整的例子(注意我已经广泛地修改您的代码并没有测试它,这只是给你一个总体思路我也摆脱了大部分的final关键字的代码。可读性,除此之外,如果您没有具体的理由使用不同的线程来运行程序,则不需要在新的Runnable()中运行WindowBuilderTest,请参阅注释部分)。

import java.awt.Color; 
import java.util.*; 

public class WindowBuilderTest extends JFrame 
{ 

private JPanel contentPane; 
private FontChanger fChanger; //<--NEW 
private JTextArea txtTop; //<--NEW 
private List<CheckBox> checkBoxes; //<--NEW 

//Launch the application. 
public static void main(final String[] args) 
{ 
    EventQueue.invokeLater(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      try 
      { 
       WindowBuilderTest frame = new WindowBuilderTest(); 
       frame.setVisible(true); 
      } 
      catch (final Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    //just use this and comment out the whole Eventqueue block. 
    /* 
    WindowBuilderTest frame = new WindowBuilderTest(); 
    frame.setVisible(true); 
    */ 
} 

// Creating Frame 
public WindowBuilderTest() 
{ 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setBounds(100, 100, 1280, 720); 
    this.contentPane = new JPanel(); 
    this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(this.contentPane); 
    this.contentPane.setLayout(null); 

    // Create Font 
    Font headfont = new Font("Serif", Font.PLAIN, 15); 
    Font headfontRed = new Font("Serif", Font.PLAIN, 15); 

    // Role Headlines 
    txtTop = new JTextArea(); //<--NEW 
    fChanger = new FontChanger(txtTop); //<--NEW 
    checkBoxes = new ArrayList<CheckBox>(); //<-- NEW you will need to update your imports. 

    txtTop.setEditable(false); 
    txtTop.setText("TOP"); 
    txtTop.setBounds(180, 95, 32, 23); 
    this.contentPane.add(txtTop); 

    final JTextArea txtMid = new JTextArea(); 
    txtMid.setEditable(false); 
    txtMid.setText("MID"); 
    txtMid.setBounds(252, 95, 32, 23); 
    this.contentPane.add(txtMid); 

    final JTextArea txtJng = new JTextArea(); 
    txtJng.setEditable(false); 
    txtJng.setText("JNG"); 
    txtJng.setBounds(320, 95, 32, 23); 
    this.contentPane.add(txtJng); 

    final JTextArea txtAdc = new JTextArea(); 
    txtAdc.setEditable(false); 
    txtAdc.setText("ADC"); 
    txtAdc.setBounds(389, 95, 32, 23); 
    this.contentPane.add(txtAdc); 

    final JTextArea txtSup = new JTextArea(); 
    txtSup.setEditable(false); 
    txtSup.setText("SUP"); 
    txtSup.setBounds(453, 95, 32, 23); 
    this.contentPane.add(txtSup); 

    // Checkbox 1st row 
    addCheckBox(183, 143, 23, 23, txtTop); 
    addCheckBox(255, 143, 23, 23, txtMid); 
    addCheckBox(322, 143, 23, 23, txtJng); 
    addCheckBox(393, 143, 23, 23, txtAdc); 
    addCheckBox(457, 143, 23, 23, txtSup); 

    // Checkbox 2nd row 
    addCheckBox(183, 200, 23, 23, txtTop); 
    addCheckBox(255, 200, 23, 23, txtMid); 
    addCheckBox(322, 200, 23, 23, txtJng); 
    addCheckBox(393, 200, 23, 23, txtAdc); 
    addCheckBox(457, 200, 23, 23, txtSup); 

    // Checkbox 3nd row 
    addCheckBox(183, 257, 23, 23, txtTop); 
    addCheckBox(255, 257, 23, 23, txtMid); 
    addCheckBox(322, 257, 23, 23, txtJng); 
    addCheckBox(393, 257, 23, 23, txtAdc); 
    addCheckBox(457, 257, 23, 23, txtSup); 
} 


private void addCheckBox(int x, int y, int width, int height) 
{ 
    JCheckBox checkBox = new JCheckBox(); 
    checkBoxes.add(checkBox); // <-- NEW (add to checkboxes list) 
    checkBox.setBounds(x, y, width, height); 
    checkBox.addItemListener(fChanger); // <-- NEW (add the same listener to all) 
    this.contentPane.add(checkBox); 
} 

class FontChanger implements ItemListener 
{ 
    private JTextArea textArea; 

    public FontChanger(JTextArea textArea) 
    { 
     this.textArea = textArea; 
    } 

    @Override 
    public void itemStateChanged(ItemEvent e) 
    { 
     if (e.getStateChange() == ItemEvent.SELECTED) 
     { 
      Font boldFont = this.textArea.getFont().deriveFont(Font.BOLD); 
      this.textArea.setForeground(Color.RED); 
      this.textArea.setFont(boldFont); 
     } 
     else 
     { 
      //iterate through list of checkboxes to see if there's still one selected. 
      boolean stillOneCheckBoxSelected = false; 
      for(int i = 0; i < checkBoxes.size(); i++){ 
       if(checkBoxes.get(i).isSelected()){ // <- Verify the method here, not sure 
        stillOneCheckBoxSelected = true; 
        break; 
       } 
      } 
      if(!stillOneCheckBoxSelected){//if no check boxes are selected, reset 
       Font boldFont = this.textArea.getFont().deriveFont(Font.PLAIN); 
       this.textArea.setForeground(Color.BLACK); 
       this.textArea.setFont(boldFont); 
      } 
     } 
    } 
} 

再一次,我没有测试过这个,你可能需要修补东西,但我认为你可以从这里继续。 这里是对的JavaDoc的ArrayList的链接,你可能想咨询的是:ArrayList JavaDoc

第二个编辑: 我重读你的问题,你真正想要这个逻辑,只有一组特定的列,所以您必须更改逻辑以将相关复选框添加到列表中,以便每次执行检查时只检查相关的复选框。

+0

感谢您的回答:)我了解一般概念,但我不确定自己能够如何实现它。你能通过给我一个粗略的起点来帮助我吗? – Gomox

+0

你的WindowBuilderTest类应该有一个'private FontChanger fChanger;'变量。在你的构造函数开始时,你实例化了这样的变量: '..//角色标题 final JTextArea txtTop = new JTextArea(); fChanger = new FontChanger(txtTop); ..' 然后,您继续添加您的复选框与相同的addCheckBox()方法,但相反,您的方法将看起来像: 'private void addCheckBox [..] final JCheckBox checkBox =新的JCheckBox(); 复选框。setBounds(x,y,width,height); checkBox.addItemListener(fChanger); ..' 然后改变你的itemStateChanged()。 – schwarz

+0

如果这仍然不清楚,我可以更新我以前的答案与更多的细节。 – schwarz