2

像这样具有几乎相同块的代码让我畏缩。再加上它加起来你有一千行代码,其中一半就足够了。当然,有一种方法可以创建一个循环来实现这一切,并且没有看起来如此简单和无脑的代码。

这样做似乎会添加尽可能多的代码,因为我试图减少:循环制作 5 个按钮,按钮的标签数组,背景数组......也许更多。即使事实证明这是可以接受的,我将如何制作一个循环来处理听众?我不能有一组方法,可以吗?我想这样的循环必须包含一个switch. 是的?如果我不想寻求更好的解决方案,我可能会这样做。所以我问...

什么样的代码会听取整个按钮组并根据按下的按钮采取行动?我会将单个侦听器分配给哪个组件?如何?

(如果我意识到我已经知道如何做到这一点并且甚至不需要一开始就问,那么这个问题的答案可能会让我更加畏缩,而不是代码的重复性,但我'无论如何我都在问。我正处于大脑想要退出的那些我今天已经拥有它的点之一。)

  private void makeScoremasterBonuses(){
    pnlBonuses = new JPanel(new GridLayout(1, 6));
    pnlBonuses.setSize(6,1);

    JButton t1 = (new JButton("3W"));
    t1.setToolTipText("This is a triple-word cell.");
    t1.setBackground(TRIPLE_WORD);
    t1.setHorizontalAlignment(JButton.CENTER);
    t1.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Highlighter.shadeSymmetric(currentCell,TRIPLE_WORD);
      }});

    JButton t2 = (new JButton("3L"));
    t2.setToolTipText("This is a triple-letter cell");
    t2.setBackground(TRIPLE_LETTER);
    t2.setHorizontalAlignment(JButton.CENTER);
    t2.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Highlighter.shadeSymmetric(currentCell,TRIPLE_LETTER);
      }});

    JButton t3 = (new JButton("2W"));
    t3.setToolTipText("This is a double-word cell");
    t3.setBackground(DOUBLE_WORD);
    t3.setHorizontalAlignment(JButton.CENTER);
    t3.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Highlighter.shadeSymmetric(currentCell,DOUBLE_WORD);
      }});

    JButton t4 = (new JButton("2L"));
    t4.setToolTipText("This is a double-letter cell");
    t4.setBackground(DOUBLE_LETTER);
    t4.setHorizontalAlignment(JButton.CENTER);
    t4.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Highlighter.shadeSymmetric(currentCell,DOUBLE_LETTER);
      }});

    JButton t5 = (new JButton(""));
    t5.setToolTipText("No bonus");
    t5.setBackground(WHITE);
    t5.setHorizontalAlignment(JButton.CENTER);
    t5.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        Highlighter.shadeSymmetric(currentCell,B_NORMAL);
      }});

    pnlBonuses.add(new JLabel("Legend: "));
    pnlBonuses.add(t1);    
    pnlBonuses.add(t2);     
    pnlBonuses.add(t3);     
    pnlBonuses.add(t4);     
    pnlBonuses.add(t5);

  }

我不是要求任何人编写代码。我什至不想那样(但我不能忽视它!)。

以下是上面代码的作用: 在此处输入图像描述

4

5 回答 5

3

通常,每当您重复使用类似的功能时,您都希望将该代码提取到一个辅助方法中,如下所示:

private JButton makeJButton(String label, String toolTip, Color bgColor, final Color highlight) {
    JButton button = new JButton(label);
    button.setToolTipText(toolTip);
    button.setBackground(bgColor);
    button.setHorizontalAlignment(JButton.CENTER);
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            Highlighter.shadeSymmetric(currentCell, highlight);
        }
    });
    return button;
}

然后你的makeScoremasterBonuses()方法就变得简单多了:

private void makeScoremasterBonuses() {
    pnlBonuses = new JPanel(new GridLayout(1, 6));
    pnlBonuses.setSize(6, 1);

    pnlBonuses.add(new JLabel("Legend: "));
    pnlBonuses.add(makeJButton("3W", "This is a triple-word cell.", TRIPLE_WORD, TRIPLE_WORD));
    pnlBonuses.add(makeJButton("3L", "This is a triple-letter cell.", TRIPLE_LETTER, TRIPLE_LETTER));
    pnlBonuses.add(makeJButton("2W", "This is a double-word cell.", DOUBLE_WORD, DOUBLE_WORD));
    pnlBonuses.add(makeJButton("3L", "This is a double-letter cell.", DOUBLE_LETTER, DOUBLE_LETTER));
    pnlBonuses.add(makeJButton("", "No bonus.", WHITE, B_NORMAL));
}
于 2014-05-30T21:17:57.227 回答
2

识别变化的方面,收集它们,并迭代收集。

像这样的东西(未经测试):

pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6,1);
pnlBonuses.add(new JLabel("Legend: "));

// Create class "CellInfo" with constructor and getters for desired properties.
CellInfo cellInfos[] = {
  new CellInfo("3W", "This is a triple-word cell.",   TRIPLE_WORD),
  new CellInfo("3L", "This is a triple-letter cell.", TRIPLE_LETTER),
  // ...
};

// Add a button for each item described by the cellInfos.
for (CellInfo cellInfo : cellInfos) {
  Button b = new JButton(cellInfo.getLabel());
  b.setToolTipText(cellInfo.getToolTipText());
  b.setBackground(cellInfo.getBackground());
  b.setHorizontalAlignment(JButton.CENTER);
  b.addActionListener(new ActionListener() {
  @Override public void actionPerformed(ActionEvent e) {
    Highlighter.shadeSymmetric(currentCell, cellInfo.getBackground());
  }});
  pnlBonuses.add(b);
}

请注意,您可能需要为占位符创建一些“最终”变量,以便在内部匿名类中使用,但这个想法应该可行。

于 2014-05-30T21:16:02.743 回答
2

enum可以是你的朋友。这几乎是一系列方法

static enum Btn {

    TripleWord("3W", "This is a triple word cell.", TRIPLE_WORD),
    TripleLetter("3L", "This is a triple letter cell.", TRIPLE_LETTER),
    DoubleWord("2W", "This is a double word cell.", DOUBLE_WORD),
    DoubleLetter("2L", "This is a double letter cell.", DOUBLE_LETTER),
    NoBonus("", "No bonus.", WHITE, B_NORMAL);
    final String label;
    final String tooltip;
    final Color color;
    final Color shade;

    Btn(String label, String tooltip, Color color, Color shade) {
        this.label = label;
        this.tooltip = tooltip;
        this.color = color;
        this.shade = shade;
    }

    Btn(String label, String tooltip, Color color) {
        this(label, tooltip, color, color);
    }

    public JButton asJButton() {
        JButton btn = (new JButton(label));
        btn.setToolTipText(tooltip);
        btn.setBackground(color);
        btn.setHorizontalAlignment(JButton.CENTER);
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Highlighter.shadeSymmetric(currentCell, shade);
            }
        });
        return btn;
    }
}

private void makeScoremasterBonuses() {
    int nBtns = Btn.values().length;
    JPanel pnlBonuses = new JPanel(new GridLayout(1, nBtns + 1));
    pnlBonuses.setSize(nBtns + 1, 1);
    pnlBonuses.add(new JLabel("Legend: "));
    for (Btn btn : Btn.values()) {
        pnlBonuses.add(btn.asJButton());
    }
}
于 2014-05-30T23:24:40.610 回答
1

(我知道我可以编辑我之前的答案,但这个答案很不一样......)

感谢@OldCurmudgeon,我想出了我认为非常好的方法。

这是“证明”(我可能会保留每个标签和工具提示):

在此处输入图像描述

  public enum Colors {
    TRIPLE_WORD    (255, 220,  50), 
    TRIPLE_LETTER  (255, 255, 150), 
    DOUBLE_WORD    (  0, 255,   0), 
    DOUBLE_LETTER  (214, 245, 214),
    NOT_A_BONUS    (255, 255, 255);

    private final int red, green, blue;

    Colors(int r, int g, int b){
      this.red   = r;
      this.green = g;
      this.blue  = b;
     }

    public java.awt.Color background(Colors c){
      return new java.awt.Color(c.red, c.green, c.blue);
    }
  }

  private void makeScoremasterBonuses(){
    Colors c;
    Colors all   [] = Colors.values();
    String labels[] = new String[all.length];
    String abbrs [] = new String[all.length];

    JButton but;
    pnlBonuses = new JPanel();
    pnlBonuses.add(new JLabel("Legend:"));

    for (int i = 0; i < all.length; i++) {
      labels[i] = all[i].name().replace("_", " ").toLowerCase();
      abbrs [i] = abbreviate(all[i].name());
      c = Colors.values()[i];
      but = new JButton(abbrs[i]);
      but.setToolTipText(labels[i]);
      but.setBackground(c.background(c));
      but.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
      but.setActionCommand("" + i);
      but.addActionListener(this);
      pnlBonuses.add(but);
    }
  }
于 2014-05-31T23:59:16.520 回答
0

=== 这是我一小时前发布的内容的主要编辑 ===

我想看看我是否可以实现自己的幼稚方法。这里是:

public class Game implements ActionListener{

  public Color [] backgrounds = {TRIPLE_WORD, TRIPLE_LETTER, 
                                 DOUBLE_WORD, DOUBLE_LETTER, B_NORMAL};

  private void makeScoremasterBonuses(){
    String[] labels = {"3W", "3L", "2W", "2L", "  "};
    JButton but;

    pnlBonuses = new JPanel();
    pnlBonuses.add(new JLabel("Legend:"));

    for (int i = 0; i < labels.length; i++) {
      char wt = labels[i].charAt(0);
      char tp = labels[i].charAt(1);
      but = new JButton(labels[i]);//("" + i);
      but.setBackground(backgrounds[i]);
      but.setHorizontalAlignment(SwingConstants.CENTER);
      but.setActionCommand("" + i);
      but.addActionListener(this);
      but.setToolTipText("This is a " 
          + (i == labels.length - 1 ? "non-bonus" :
                          (wt == '3' ? "triple" : "double") 
                  + " " + (tp == 'L' ? "letter" : "word")) 
          + " cell.");
      pnlBonuses.add(but);
    }    
  }

  public void actionPerformed(ActionEvent evt) {
    int i = Integer.parseInt(evt.getActionCommand());
    Highlighter.shadeSymmetric(currentCell,backgrounds[i]);
  }

这现在(编辑后)甚至是我发起的最好的线程,就响应的质量和我从中学到的一切而言。谢谢你们。

但我仍然没有设法适当地使用setActionCommand. 无论我为尝试使用它所做的一切最终都会在代码方面变得如此之长,以至于我放弃了并选择了简短而简单但不合适的方法。

关于如何使用 set...getActionCommand正确方式(即,作为操作)的任何想法,而无需添加大量代码来做到这一点?

于 2014-05-31T02:03:01.943 回答