package jrummikub.view.impl; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Point; import java.awt.Polygon; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollBar; import javax.swing.JViewport; import javax.swing.SwingConstants; import javax.swing.border.LineBorder; import javax.swing.border.MatteBorder; import jrummikub.model.GameSettings; import jrummikub.view.ISidePanel; @SuppressWarnings("serial") class SidePanel extends JPanel implements ISidePanel { InfoPanel infoPanel; PlayerListPanel playerListPanel; BottomScrollPane playerListScrollPane; private JLabel initialMeldLabel; private JLabel setNumberLabel; private JLabel highestValueLabel; private JLabel handStonesLabel; private JLabel jokerLabel; private JLabel noLimitsLabel; private JLabel colorLabel; public SidePanel() { setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); infoPanel = new InfoPanel(createRuleInfoPanel()); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.fill = GridBagConstraints.BOTH; infoPanel.setBorder(new MatteBorder(0, 0, 1, 1, Color.BLACK)); add(infoPanel, c); playerListPanel = new PlayerListPanel(); c.gridx = 0; c.gridy = 1; c.weighty = 1; c.weightx = 1; c.fill = GridBagConstraints.BOTH; playerListScrollPane = new BottomScrollPane(playerListPanel); playerListScrollPane .setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK)); add(playerListScrollPane, c); } @Override public void setGameSettings(GameSettings settings) { initialMeldLabel.setText("" + settings.getInitialMeldThreshold()); setNumberLabel.setText("" + settings.getStoneSetNumber()); highestValueLabel.setText("1 - " + settings.getHighestValue()); handStonesLabel.setText("" + settings.getNumberOfStonesDealt()); jokerLabel.setText("" + settings.getJokerNumber()); colorLabel.setText("" + settings.getStoneColors().size()); noLimitsLabel.setVisible(settings.isNoLimits()); } private JPanel createRuleInfoPanel() { JPanel panel = new JPanel(); panel.setLayout(new GridBagLayout()); initialMeldLabel = createRuleLine(panel, "Auslegeschranke", 0); setNumberLabel = createRuleLine(panel, "Steins\u00e4tze", 1); highestValueLabel = createRuleLine(panel,"Steinwert", 2); handStonesLabel = createRuleLine(panel, "Startsteine", 3); jokerLabel = createRuleLine(panel, "Joker", 4); colorLabel = createRuleLine(panel, "Farben", 5); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 6; c.gridwidth = 2; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.CENTER; noLimitsLabel = new JLabel("No Limits"); noLimitsLabel.setHorizontalAlignment(SwingConstants.CENTER); panel.add(noLimitsLabel, c); return panel; } private JLabel createRuleLine(JPanel panel, String name, int line) { GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = line; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; panel.add(new JLabel(name + ": "), c); JLabel label = new JLabel(""); label.setHorizontalAlignment(SwingConstants.RIGHT); c.weightx = 0; c.gridx = 1; c.anchor = GridBagConstraints.EAST; panel.add(label, c); return label; } @SuppressWarnings("serial") class BottomScrollPane extends JPanel { JComponent content; JViewport viewport; JScrollBar scrollBar; boolean scrollToBottom; public BottomScrollPane(JComponent content) { setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.BOTH; viewport = new JViewport(); add(viewport, c); this.content = content; viewport.setView(content); scrollBar = new JScrollBar(JScrollBar.VERTICAL); scrollBar.setBorder(new LineBorder(Color.BLACK, 0)); c.weightx = 0; add(scrollBar, c); ComponentAdapter resizeListener = new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { onResize(); } }; addComponentListener(resizeListener); content.addComponentListener(resizeListener); scrollBar.addAdjustmentListener(new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent arg0) { scrollViewport(); } }); scrollToBottom(); } public void scrollToBottom() { scrollToBottom = true; } private void onResize() { int oldValue = 0; if (!scrollToBottom) { oldValue = scrollBar.getMaximum() - scrollBar.getVisibleAmount() - scrollBar.getValue(); } scrollToBottom = false; int max = content.getHeight(); int extent = viewport.getHeight(); int value = Math.max(0, max - extent - oldValue); scrollBar.setVisible(extent != max); scrollBar.setValues(value, extent, 0, max); scrollViewport(); } private void scrollViewport() { viewport.setViewPosition(new Point(0, scrollBar.getValue())); } } static class InfoPanel extends JPanel { JPanel ruleInfoPanel; JCheckBox showRules; public InfoPanel(JPanel ruleInfo) { ruleInfoPanel = ruleInfo; setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); showRules = new JCheckBox("Regeln"); showRules.setSelected(true); c.gridx = 0; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; setupTriangleIcons(showRules); c.insets = new Insets(0, 4, 0, 4); add(showRules, c); showRules.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg) { boolean selected = showRules.isSelected(); ruleInfoPanel.setVisible(selected); showRules.setPressedIcon(selected ? showRules.getIcon() : showRules.getSelectedIcon()); } }); c.insets = new Insets(4, 8, 4, 8); add(ruleInfoPanel, c); } private void setupTriangleIcons(JCheckBox test) { BufferedImage img1 = new BufferedImage(8, 8, BufferedImage.TYPE_3BYTE_BGR); BufferedImage img2 = new BufferedImage(8, 8, BufferedImage.TYPE_3BYTE_BGR); Graphics2D g = img1.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(getBackground()); g.fillRect(0, 0, 8, 8); g.setColor(Color.BLACK); Polygon p = new Polygon(); p.addPoint(0, 0); p.addPoint(8, 4); p.addPoint(0, 8); g.fillPolygon(p); g = img2.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(getBackground()); g.fillRect(0, 0, 8, 8); g.setColor(Color.BLACK); p = new Polygon(); p.addPoint(0, 0); p.addPoint(4, 8); p.addPoint(8, 0); g.fillPolygon(p); test.setIcon(new ImageIcon(img1)); test.setSelectedIcon(new ImageIcon(img2)); test.setPressedIcon(new ImageIcon(img1)); test.setRolloverEnabled(false); test.setFocusPainted(false); } } class PlayerListItem extends JPanel { JLabel playerName; public PlayerListItem() { setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(5, 5, 5, 5); playerName = new JLabel("Horst
> 9000 Steine"); add(playerName, c); } } class PlayerListPanel extends JPanel { JPanel startSpacer; public PlayerListPanel() { setBackground(Color.GRAY); setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); startSpacer = new JPanel(); startSpacer.setBackground(Color.GRAY); startSpacer.setPreferredSize(new Dimension(0, 0)); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.BOTH; add(startSpacer, c); c.weighty = 0; c.fill = GridBagConstraints.HORIZONTAL; for (int i = 1; i <= 4; i++) { c.gridx = 0; c.gridy = i; c.insets = new Insets(i == 1 ? 0 : 1, 0, 0, 0); add(new PlayerListItem(), c); } } @Override public Dimension getPreferredSize() { Dimension oldPref = super.getPreferredSize(); return new Dimension(0, oldPref.height); } } }