如何概括这些重复的代码块?

时间:2014-05-30 21:08:26

标签: java jcomponent generalization

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

看起来像这样做会增加尽可能多的代码,我想减少:循环制作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);

  }

我不是要求任何人写代码;我甚至不想要那个(但我无法忽视它!)。

以上代码的作用如下: enter image description here

5 个答案:

答案 0 :(得分: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));
}

答案 1 :(得分: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);
}

请注意,您可能需要为内部匿名类创建一些占位符的“最终”变量,但这个想法应该有效。

答案 2 :(得分: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());
    }
}

答案 3 :(得分:1)

(我知道我可以编辑我之前的答案,但这个答案如此不同......)

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

这里"证明" (我可以按原样保留每个标签和工具提示):

enter image description here

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

答案 4 :(得分: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正确方法(即作为操作)的任何想法,而不添加大量代码吗?< /强>