如何使用Java Swing绘制锦标赛括号?[关闭]

7kjnsjlb  于 5个月前  发布在  Java
关注(0)|答案(1)|浏览(52)

已关闭。此问题需要更多focused。目前不接受回答。
**要改进此问题吗?**更新此问题,使其仅针对editing this post的一个问题。

5天前关闭。
Improve this question
我有以下匹配类:

public class Match implements Serializable {
    private String homeTeam;
    private String awayTeam;
    private int homeGoals;
    private int awayGoals;
}

字符串
现在,锦标赛是一个单淘汰赛,最好的3,这意味着两支球队将对彼此进行三次比赛,谁赢得了最多的比赛进入下一轮,而谁失去了最多的比赛被淘汰。
注意事项:如果一个队在一轮中赢得了前两场比赛,那么第三场比赛就不进行了,因为它不会保存另一个队,所以在这种情况下只进行两场比赛。而如果已经进行了所有三场比赛,球队有相同的胜利次数(因为他们平局了一场或多场比赛),那么将进行额外的比赛,直到有一个赢家。
这意味着在锦标赛中,通常每轮进行三场比赛,但也可能发生两场,四场甚至五场比赛。
问题是,拥有一个包含所有已播放比赛的比赛数组列表,如下所示:

//Pseudo-code
{
Manchester, Barcelona, 1, 0; //Semifinal 1
Barcelona, Manchester, 1, 1; //Semifinal 1
Manchester, Barcelona, 2, 1; //Semifinal 1
Milan, Dortmund, 0, 3; //Semifinal 2
Dortmund, Milan, 1, 0; //Semifinal 2
Manchester, Dortmund, 0, 0; //Final
Dortmund, Manchester, 1, 1; //Final
Manchester, Dortmund, 0, 0; //Final
Dortmund, Manchester, 2, 3; //Final
}


我如何使用Swing编码一个代表上述比赛的锦标赛括号?类似这样:
Tournament bracket for the above matches
谢谢你,谢谢
P.S.:它必须适用于任意数量的团队(总是2的幂)。
我唯一尝试的是有一个显示所有比赛的JTable,但它很难阅读,弄清楚谁进入下一轮,谁被淘汰是我的全部脑力。

wvmv3b1j

wvmv3b1j1#

Swing有很多布局管理器,你可以使用它们,并将它们合并(参见https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)用于GUI的不同部分。你可以将绘图问题分成几个子问题,这些问题可以单独解决。没有花哨的线条绘制,你可以看到一个团队在下一轮中前进到目标括号的位置,你可以将绘图问题分成以下步骤:

  • 将每一轮显示为JPanel s的水平列表,每轮一个面板。
  • 将一轮比赛中的每个比赛显示为JPanel s的垂直列表,每个比赛一个面板。
  • 在比赛面板中显示有关球队的信息,他们打了多少场比赛,赢了多少场比赛。

假设要显示的信息存储在List<List<String[]>>对象中,外部的List<...>将是回合列表,内部的List<...>将是比赛列表(在该回合中),String[]数组是两个球队名称的列表。然后下面的方法将为整个锦标赛创建一个JPanel,每个回合的JPanel s:

private static JPanel createTournamentPanel(List<List<String[]>> rounds) {
    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(1, 0));
    for(List<String[]> round : rounds) {
        JPanel roundPanel = createRoundPanel(round);
        panel.add(roundPanel);
    }
    return panel;
}

字符串
此面板使用GridLayout显示其内容(圆角)在一行和任意列(new GridLayout(1, 0))中。因此,添加到该面板的组件将从左到右显示在一行中。GridLayout还将调整添加到JPanel的所有组件的宽度,使它们具有相同的宽度(参见https://docs.oracle.com/javase/tutorial/uiswing/layout/grid.html)。
以下方法将为一轮比赛中的比赛创建JPanel

private static JPanel createRoundPanel(List<String[]> pairings) {
    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(0, 1));
    for(String[] pairing: pairings) {
        JPanel pairingPanel = createMatchPanel(pairing[0], pairing[1]);
        panel.add(pairingPanel);
    }
    return panel;
}


这里再次使用了GridLayout,但是这次组件从上到下被定向在一列中,并且具有任意数量的行(new GridLayout(0, 1))。由于它是GridLayout,因此添加到该面板的组件的高度也都相同。
下面的方法fill为两支球队之间的一场比赛创建JPanel

private static JPanel createMatchPanel(String firstTeam, String secondTeam) {
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    panel.add(Box.createVerticalGlue());
    panel.add(new JLabel(firstTeam));
    panel.add(new JLabel(secondTeam));
    panel.add(Box.createVerticalGlue());
    return panel;
}


正如你所看到的,它是一个非常简化的版本,因为它只显示球队名称,没有正在进行的比赛或谁是赢家的指示。这个面板使用BoxLayout(见https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html)来排列组件,因为我需要“间隔”显示球队名称时。
这些helper方法可以创建一个(简化的)锦标赛视图,如下所示:
x1c 0d1x的数据
由于Swing/AWT中的布局管理器会自动为您调整组件的大小,因此当框架/面板的大小更改时,您不需要做任何事情。这是当大小更改时相同框架/面板的外观:



出于教育目的,我给匹配面板一个边框来显示生成的面板的大小,以及Swing/AWT及其布局管理器如何控制大小:

这也说明了为什么我需要“spacers”(Box.createVerticalGlue()),因为球队的名字应该在面板的中间显示在一起(这有一个巨大的高度)。还要注意,在一个圆形列的比赛面板如何具有相同的高度和比赛面板中的圆形面板如何具有相同的宽度。
如前所述,这里的createMatchPanel()方法是为比赛数据创建一个非常简化的面板。这只是为了显示锦标赛面板,回合面板和比赛面板是如何创建和相互交互的。您可以调整createMatchPanel()方法以显示更复杂的比赛布局,包括一个游戏的列表和指示赢家。但你只需要调整这个特定的方法来改变JPanel的比赛数据。其他的问题,如何显示所有比赛在一轮,如何显示比赛的所有回合已经通过其他方法createTournamentPanel()createRoundPanel()解决了。您可以使用GridBagLayout创建不同的JPanel(参见https://docs.oracle.com/javase/8/docs/api/javax/swing/BoxLayout.html)来创建更复杂的比赛信息布局。

相关问题