From 5667ab5e1cd7ea041f25b72b19dcc4380e656524 Mon Sep 17 00:00:00 2001 From: lantzelot-swe <75668734+lantzelot-swe@users.noreply.github.com> Date: Sat, 11 Nov 2023 00:20:06 +0100 Subject: [PATCH] feat: add THEGamepad to the "edit controller" dialog --- src/main/java/se/lantz/gui/BaseDialog.java | 2 +- .../se/lantz/gui/gamepad/GamePadDialog.java | 41 +++- ...el.java => TheGamepadBackgroundPanel.java} | 22 +- .../gui/gamepad/TheGamepadImagePanel.java | 129 ++++++++++ .../gui/gamepad/TheGamepadInfoPanel.java | 77 ++++++ .../gamepad/TheGamepadMappingComponent.java | 220 ++++++++++++++++++ .../gui/gamepad/TheGamepadMappingPanel.java | 163 +++++++++++++ .../gamepad/USBControllerBackgroundPanel.java | 66 ++++++ ...anel.java => USBControllerImagePanel.java} | 12 +- ...Panel.java => USBControllerInfoPanel.java} | 4 +- ...ava => USBControllerMappingComponent.java} | 12 +- ...el.java => USBControllerMappingPanel.java} | 98 ++++---- src/main/resources/se/lantz/TheGamepad.png | Bin 0 -> 42961 bytes .../resources/se/lantz/TheGamepadMapping.png | Bin 0 -> 4098 bytes 14 files changed, 763 insertions(+), 83 deletions(-) rename src/main/java/se/lantz/gui/gamepad/{GamepadBackgroundPanel.java => TheGamepadBackgroundPanel.java} (75%) create mode 100644 src/main/java/se/lantz/gui/gamepad/TheGamepadImagePanel.java create mode 100644 src/main/java/se/lantz/gui/gamepad/TheGamepadInfoPanel.java create mode 100644 src/main/java/se/lantz/gui/gamepad/TheGamepadMappingComponent.java create mode 100644 src/main/java/se/lantz/gui/gamepad/TheGamepadMappingPanel.java create mode 100644 src/main/java/se/lantz/gui/gamepad/USBControllerBackgroundPanel.java rename src/main/java/se/lantz/gui/gamepad/{GamePadImagePanel.java => USBControllerImagePanel.java} (92%) rename src/main/java/se/lantz/gui/gamepad/{GamePadInfoPanel.java => USBControllerInfoPanel.java} (97%) rename src/main/java/se/lantz/gui/gamepad/{MappingComponent.java => USBControllerMappingComponent.java} (93%) rename src/main/java/se/lantz/gui/gamepad/{GamePadMappingPanel.java => USBControllerMappingPanel.java} (60%) create mode 100644 src/main/resources/se/lantz/TheGamepad.png create mode 100644 src/main/resources/se/lantz/TheGamepadMapping.png diff --git a/src/main/java/se/lantz/gui/BaseDialog.java b/src/main/java/se/lantz/gui/BaseDialog.java index ec9fe85..63ff25b 100644 --- a/src/main/java/se/lantz/gui/BaseDialog.java +++ b/src/main/java/se/lantz/gui/BaseDialog.java @@ -51,7 +51,7 @@ public class BaseDialog extends JDialog getRootPane().setDefaultButton(getOkButton()); } - protected void addContent(JPanel panel) + protected void addContent(JComponent panel) { getBackgroundPanel().add(panel, BorderLayout.CENTER); } diff --git a/src/main/java/se/lantz/gui/gamepad/GamePadDialog.java b/src/main/java/se/lantz/gui/gamepad/GamePadDialog.java index 0591570..9df8e6b 100644 --- a/src/main/java/se/lantz/gui/gamepad/GamePadDialog.java +++ b/src/main/java/se/lantz/gui/gamepad/GamePadDialog.java @@ -3,39 +3,64 @@ package se.lantz.gui.gamepad; import java.awt.Dimension; import java.awt.Frame; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + import se.lantz.gui.BaseDialog; import se.lantz.model.JoystickModel; public class GamePadDialog extends BaseDialog { - private GamepadBackgroundPanel panel; + private JTabbedPane tabbedPane; + private USBControllerBackgroundPanel usbControlerBackroundPanel; + private TheGamepadBackgroundPanel theGamePadBackroundPanel; private JoystickModel model; - private Dimension dialogSize = new Dimension(660, 790); + private Dimension dialogSize = new Dimension(660, 810); public GamePadDialog(Frame owner, JoystickModel model) { super(owner); //Create a separate model so that changes can be cancelled this.model = new JoystickModel(model.isPort1()); - setTitle("Edit joystick/gamepad configuration"); - addContent(getGamepadBackgroundPanel()); + setTitle("Edit THEGamepad/USB Controller configuration"); + addContent(getTabbedPane()); this.setPreferredSize(dialogSize); this.setResizable(false); //Set initial values to the model this.model.setConfigStringFromDb(model.getConfigString()); } - private GamepadBackgroundPanel getGamepadBackgroundPanel() + private USBControllerBackgroundPanel getUSBControllerBackgroundPanel() { - if (panel == null) + if (usbControlerBackroundPanel == null) { - panel = new GamepadBackgroundPanel(model); + usbControlerBackroundPanel = new USBControllerBackgroundPanel(model); } - return panel; + return usbControlerBackroundPanel; + } + + private TheGamepadBackgroundPanel getTheGamepadBackgroundPanel() + { + if (theGamePadBackroundPanel == null) + { + theGamePadBackroundPanel = new TheGamepadBackgroundPanel(model); + } + return theGamePadBackroundPanel; } public String getJoyConfigString() { return this.model.getConfigString(); } + + private JTabbedPane getTabbedPane() + { + if (tabbedPane == null) + { + tabbedPane = new JTabbedPane(); + tabbedPane.addTab("THEGamepad", getTheGamepadBackgroundPanel()); + tabbedPane.addTab("Alternative USB controller", getUSBControllerBackgroundPanel()); + } + return tabbedPane; + } } diff --git a/src/main/java/se/lantz/gui/gamepad/GamepadBackgroundPanel.java b/src/main/java/se/lantz/gui/gamepad/TheGamepadBackgroundPanel.java similarity index 75% rename from src/main/java/se/lantz/gui/gamepad/GamepadBackgroundPanel.java rename to src/main/java/se/lantz/gui/gamepad/TheGamepadBackgroundPanel.java index 495790a..ddf06a9 100644 --- a/src/main/java/se/lantz/gui/gamepad/GamepadBackgroundPanel.java +++ b/src/main/java/se/lantz/gui/gamepad/TheGamepadBackgroundPanel.java @@ -8,13 +8,13 @@ import javax.swing.JPanel; import se.lantz.model.JoystickModel; -public class GamepadBackgroundPanel extends JPanel +public class TheGamepadBackgroundPanel extends JPanel { - private GamePadInfoPanel gamePadInfoPanel; - private GamePadImagePanel gamePadImagePanel; - private GamePadMappingPanel gamePadMappingPanel; + private TheGamepadInfoPanel gamePadInfoPanel; + private TheGamepadImagePanel gamePadImagePanel; + private TheGamepadMappingPanel gamePadMappingPanel; private JoystickModel model; - public GamepadBackgroundPanel(JoystickModel model) { + public TheGamepadBackgroundPanel(JoystickModel model) { this.model = model; GridBagLayout gridBagLayout = new GridBagLayout(); setLayout(gridBagLayout); @@ -45,21 +45,21 @@ public class GamepadBackgroundPanel extends JPanel gbc_gamePadMappingPanel.gridy = 1; add(getGamePadMappingPanel(), gbc_gamePadMappingPanel); } - private GamePadInfoPanel getGamePadInfoPanel() { + private TheGamepadInfoPanel getGamePadInfoPanel() { if (gamePadInfoPanel == null) { - gamePadInfoPanel = new GamePadInfoPanel(); + gamePadInfoPanel = new TheGamepadInfoPanel(); } return gamePadInfoPanel; } - private GamePadImagePanel getGamePadImagePanel() { + private TheGamepadImagePanel getGamePadImagePanel() { if (gamePadImagePanel == null) { - gamePadImagePanel = new GamePadImagePanel(); + gamePadImagePanel = new TheGamepadImagePanel(); } return gamePadImagePanel; } - private GamePadMappingPanel getGamePadMappingPanel() { + private TheGamepadMappingPanel getGamePadMappingPanel() { if (gamePadMappingPanel == null) { - gamePadMappingPanel = new GamePadMappingPanel(model, getGamePadImagePanel()); + gamePadMappingPanel = new TheGamepadMappingPanel(model, getGamePadImagePanel()); } return gamePadMappingPanel; } diff --git a/src/main/java/se/lantz/gui/gamepad/TheGamepadImagePanel.java b/src/main/java/se/lantz/gui/gamepad/TheGamepadImagePanel.java new file mode 100644 index 0000000..e60b846 --- /dev/null +++ b/src/main/java/se/lantz/gui/gamepad/TheGamepadImagePanel.java @@ -0,0 +1,129 @@ +package se.lantz.gui.gamepad; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class TheGamepadImagePanel extends JPanel +{ + public enum TheGamepadButton + { + UP("Up", Character.toString(0x1f815)), DOWN("Down", Character.toString(0x1f817)), + LEFT("Left", Character.toString(0x1f814)), RIGHT("Right", Character.toString(0x1f816)), A("A", "TL"), B("B", "Right Fire"), + X("X", "TR"), Y("Y", "Left Fire"), LSB("LSB", "A"), RSB("RSB", "B"), MENU("Menu", "C"); + + public final String label; + public final String joyMapping; + + private TheGamepadButton(String label, String joyMapping) + { + this.label = label; + this.joyMapping = joyMapping; + } + } + + ImageIcon gamepadImage = new ImageIcon(getClass().getResource("/se/lantz/TheGamepad.png")); + private JLabel imageLabel; + + private TheGamepadButton currentButton = null; + + public TheGamepadImagePanel() + { + GridBagLayout gridBagLayout = new GridBagLayout(); + setLayout(gridBagLayout); + GridBagConstraints gbc_imageLabel = new GridBagConstraints(); + gbc_imageLabel.insets = new Insets(20, 0, 0, 0); + gbc_imageLabel.weightx = 1.0; + gbc_imageLabel.weighty = 1.0; + gbc_imageLabel.anchor = GridBagConstraints.NORTH; + gbc_imageLabel.gridx = 0; + gbc_imageLabel.gridy = 0; + add(getImageLabel(), gbc_imageLabel); + } + + private JLabel getImageLabel() + { + if (imageLabel == null) + { + imageLabel = new JLabel() + { + + @Override + protected void paintComponent(Graphics g) + { + super.paintComponent(g); + //Draw for currently focused button + drawForButton(g); + } + + }; + imageLabel.setIcon(gamepadImage); + } + return imageLabel; + } + + public void setCurrentButtonAndRepaint(TheGamepadButton button) + { + this.currentButton = button; + this.repaint(); + } + + private void drawForButton(Graphics g) + { + if (currentButton == null) + { + return; + } + + Graphics2D graphics2D = (Graphics2D) g; + graphics2D.setStroke(new BasicStroke(3.0f)); + graphics2D.setColor(Color.red); + + switch (currentButton) + { + case UP: + graphics2D.drawOval(55, 50, 22, 22); + break; + case DOWN: + graphics2D.drawOval(53, 84, 22, 22); + break; + case LEFT: + graphics2D.drawOval(40, 66, 22, 22); + break; + case RIGHT: + graphics2D.drawOval(72, 66, 22, 22); + break; + case A: + graphics2D.drawOval(253, 89, 22, 22); + break; + case B: + graphics2D.drawOval(276, 68, 22, 22); + break; + case MENU: + graphics2D.drawRect(122, 92, 25, 25); + break; + case LSB: + graphics2D.drawRect(47, 15, 25, 20); + break; + case RSB: + graphics2D.drawRect(253, 15, 25, 20); + break; + case X: + graphics2D.drawOval(230, 67, 22, 22); + break; + case Y: + graphics2D.drawOval(250, 46, 22, 22); + break; + default: + break; + } + } +} diff --git a/src/main/java/se/lantz/gui/gamepad/TheGamepadInfoPanel.java b/src/main/java/se/lantz/gui/gamepad/TheGamepadInfoPanel.java new file mode 100644 index 0000000..b5ec7c1 --- /dev/null +++ b/src/main/java/se/lantz/gui/gamepad/TheGamepadInfoPanel.java @@ -0,0 +1,77 @@ +package se.lantz.gui.gamepad; + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class TheGamepadInfoPanel extends JPanel +{ + ImageIcon compImage = new ImageIcon(getClass().getResource("/se/lantz/TheGamepadMapping.png")); + + private JLabel infoLabel; + private JLabel compImageLabel; + private JLabel extraButtonsInfoLabel; + + public TheGamepadInfoPanel() + { + setBackground(Color.WHITE); + GridBagLayout gridBagLayout = new GridBagLayout(); + setLayout(gridBagLayout); + GridBagConstraints gbc_infoLabel = new GridBagConstraints(); + gbc_infoLabel.fill = GridBagConstraints.HORIZONTAL; + gbc_infoLabel.weightx = 1.0; + gbc_infoLabel.insets = new Insets(0, 10, 0, 10); + gbc_infoLabel.gridx = 0; + gbc_infoLabel.gridy = 0; + add(getInfoLabel(), gbc_infoLabel); + GridBagConstraints gbc_compImageLabel = new GridBagConstraints(); + gbc_compImageLabel.insets = new Insets(0, 0, 10, 0); + gbc_compImageLabel.weighty = 1.0; + gbc_compImageLabel.weightx = 1.0; + gbc_compImageLabel.gridx = 0; + gbc_compImageLabel.gridy = 1; + add(getCompImageLabel(), gbc_compImageLabel); + GridBagConstraints gbc_extraButtonsInfoLabel = new GridBagConstraints(); + gbc_extraButtonsInfoLabel.insets = new Insets(0, 10, 10, 10); + gbc_extraButtonsInfoLabel.fill = GridBagConstraints.HORIZONTAL; + gbc_extraButtonsInfoLabel.gridx = 0; + gbc_extraButtonsInfoLabel.gridy = 2; + add(getExtraButtonsInfoLabel(), gbc_extraButtonsInfoLabel); + } + + private JLabel getInfoLabel() + { + if (infoLabel == null) + { + infoLabel = + new JLabel("

THEGamepad

THEGamepad from Retro Games is compatible with THEC64, THEC64 Mini, THEA500 Mini, PC, Mac & Linux. Compared with THEC64 Joystick, functions translate as follows:

"); + } + return infoLabel; + } + + private JLabel getCompImageLabel() + { + if (compImageLabel == null) + { + compImageLabel = new JLabel(); + compImageLabel.setBackground(Color.WHITE); + compImageLabel.setIcon(compImage); + } + return compImageLabel; + } + + private JLabel getExtraButtonsInfoLabel() + { + if (extraButtonsInfoLabel == null) + { + extraButtonsInfoLabel = + new JLabel("
Below are the functions for THEC64 Joystick shown in parenthesis for comparison.
"); + } + return extraButtonsInfoLabel; + } +} diff --git a/src/main/java/se/lantz/gui/gamepad/TheGamepadMappingComponent.java b/src/main/java/se/lantz/gui/gamepad/TheGamepadMappingComponent.java new file mode 100644 index 0000000..c1e2e59 --- /dev/null +++ b/src/main/java/se/lantz/gui/gamepad/TheGamepadMappingComponent.java @@ -0,0 +1,220 @@ +package se.lantz.gui.gamepad; + +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.KeyboardFocusManager; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.Beans; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import se.lantz.gui.KeySelectionComboBox; +import se.lantz.gui.gamepad.TheGamepadImagePanel.TheGamepadButton; +import se.lantz.model.JoystickModel; + +public class TheGamepadMappingComponent extends JPanel +{ + private JLabel buttonTextLabel; + private KeySelectionComboBox keySelectionComboBox; + private JLabel joyMapLabel; + private TheGamepadButton button; + private JoystickModel model; + private TheGamepadImagePanel imagePanel; + + public TheGamepadMappingComponent(TheGamepadButton button, JoystickModel model, TheGamepadImagePanel imagePanel) + { + this.button = button; + this.model = model; + this.imagePanel = imagePanel; + GridBagLayout gridBagLayout = new GridBagLayout(); + setLayout(gridBagLayout); + GridBagConstraints gbc_buttonTextLabel = new GridBagConstraints(); + gbc_buttonTextLabel.anchor = GridBagConstraints.WEST; + gbc_buttonTextLabel.insets = new Insets(5, 5, 0, 5); + gbc_buttonTextLabel.gridx = 0; + gbc_buttonTextLabel.gridy = 0; + add(getButtonTextLabel(), gbc_buttonTextLabel); + GridBagConstraints gbc_keySelectionComboBox = new GridBagConstraints(); + gbc_keySelectionComboBox.weighty = 1.0; + gbc_keySelectionComboBox.gridwidth = 2; + gbc_keySelectionComboBox.insets = new Insets(0, 4, 5, 5); + gbc_keySelectionComboBox.anchor = GridBagConstraints.NORTHWEST; + gbc_keySelectionComboBox.gridx = 0; + gbc_keySelectionComboBox.gridy = 1; + add(getKeySelectionComboBox(), gbc_keySelectionComboBox); + GridBagConstraints gbc_joyMapLabel = new GridBagConstraints(); + gbc_joyMapLabel.anchor = GridBagConstraints.WEST; + gbc_joyMapLabel.weightx = 1.0; + gbc_joyMapLabel.insets = new Insets(5, 0, 0, 5); + gbc_joyMapLabel.gridx = 1; + gbc_joyMapLabel.gridy = 0; + add(getJoyMapLabel(), gbc_joyMapLabel); + + if (!Beans.isDesignTime()) + { + model.addPropertyChangeListener((e) -> modelChanged()); + } + } + + private void modelChanged() + { + switch (button) + { + case UP: + getKeySelectionComboBox().setSelectedCode(model.getUp()); + break; + case DOWN: + getKeySelectionComboBox().setSelectedCode(model.getDown()); + break; + case LEFT: + getKeySelectionComboBox().setSelectedCode(model.getLeft()); + break; + case RIGHT: + getKeySelectionComboBox().setSelectedCode(model.getRight()); + break; + case Y: + getKeySelectionComboBox().setSelectedCode(model.getLeftFire()); + break; + case B: + getKeySelectionComboBox().setSelectedCode(model.getRightFire()); + break; + case A: + getKeySelectionComboBox().setSelectedCode(model.getTl()); + break; + case X: + getKeySelectionComboBox().setSelectedCode(model.getTr()); + break; + case LSB: + getKeySelectionComboBox().setSelectedCode(model.getA()); + break; + case RSB: + getKeySelectionComboBox().setSelectedCode(model.getB()); + break; + case MENU: + getKeySelectionComboBox().setSelectedCode(model.getC()); + break; + + default: + break; + } + } + + private JLabel getButtonTextLabel() + { + if (buttonTextLabel == null) + { + buttonTextLabel = new JLabel(button.label); + } + return buttonTextLabel; + } + + private KeySelectionComboBox getKeySelectionComboBox() + { + if (keySelectionComboBox == null) + { + keySelectionComboBox = new KeySelectionComboBox(model); + keySelectionComboBox.addActionListener(e -> { + switch (button) + { + case UP: + model.setUp(keySelectionComboBox.getSelectedCode()); + break; + case DOWN: + model.setDown(keySelectionComboBox.getSelectedCode()); + break; + case LEFT: + model.setLeft(keySelectionComboBox.getSelectedCode()); + break; + case RIGHT: + model.setRight(keySelectionComboBox.getSelectedCode()); + break; + case Y: + model.setLeftFire(keySelectionComboBox.getSelectedCode()); + break; + case B: + model.setRightFire(keySelectionComboBox.getSelectedCode()); + break; + case A: + model.setTl(keySelectionComboBox.getSelectedCode()); + break; + case X: + model.setTr(keySelectionComboBox.getSelectedCode()); + break; + case LSB: + model.setA(keySelectionComboBox.getSelectedCode()); + break; + case RSB: + model.setB(keySelectionComboBox.getSelectedCode()); + break; + case MENU: + model.setC(keySelectionComboBox.getSelectedCode()); + break; + default: + break; + } + }); + keySelectionComboBox.addMouseListener(new MouseAdapter() + { + @Override + public void mouseExited(MouseEvent e) + { + if (!keySelectionComboBox.hasFocus()) + { + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner instanceof KeySelectionComboBox) + { + TheGamepadMappingComponent focusedMappingComponent = (TheGamepadMappingComponent) SwingUtilities + .getAncestorOfClass(TheGamepadMappingComponent.class, focusOwner); + if (focusedMappingComponent != null) + { + imagePanel.setCurrentButtonAndRepaint(focusedMappingComponent.button); + } + } + else + { + imagePanel.setCurrentButtonAndRepaint(null); + } + } + } + + @Override + public void mouseEntered(MouseEvent me) + { + imagePanel.setCurrentButtonAndRepaint(button); + } + }); + keySelectionComboBox.addFocusListener(new FocusAdapter() + { + @Override + public void focusGained(FocusEvent e) + { + imagePanel.setCurrentButtonAndRepaint(button); + } + + @Override + public void focusLost(FocusEvent e) + { + imagePanel.setCurrentButtonAndRepaint(null); + } + }); + } + return keySelectionComboBox; + } + + private JLabel getJoyMapLabel() + { + if (joyMapLabel == null) + { + joyMapLabel = new JLabel("(" + button.joyMapping + ")"); + } + return joyMapLabel; + } + +} diff --git a/src/main/java/se/lantz/gui/gamepad/TheGamepadMappingPanel.java b/src/main/java/se/lantz/gui/gamepad/TheGamepadMappingPanel.java new file mode 100644 index 0000000..044c8b3 --- /dev/null +++ b/src/main/java/se/lantz/gui/gamepad/TheGamepadMappingPanel.java @@ -0,0 +1,163 @@ +package se.lantz.gui.gamepad; + +import java.awt.GridBagLayout; + +import javax.swing.JPanel; + +import se.lantz.gui.gamepad.TheGamepadImagePanel.TheGamepadButton; +import se.lantz.gui.gamepad.USBControllerImagePanel.USBControllerButton; +import se.lantz.model.JoystickModel; +import java.awt.GridBagConstraints; +import java.awt.Insets; + +public class TheGamepadMappingPanel extends JPanel +{ + private TheGamepadMappingComponent upComponent; + private JoystickModel model; + private TheGamepadMappingComponent downComponent; + private TheGamepadMappingComponent leftComponent; + private TheGamepadMappingComponent rightComponent; + private TheGamepadMappingComponent xComponent; + private TheGamepadMappingComponent yComponent; + private TheGamepadMappingComponent aComponent; + private TheGamepadMappingComponent bComponent; + private TheGamepadMappingComponent leftTriggerComponent; + private TheGamepadMappingComponent rightTriggerComponent; + private TheGamepadMappingComponent backGuideComponent; + private TheGamepadMappingComponent leftShoulderComponent; + private TheGamepadMappingComponent rightShoulderComponent; + private TheGamepadMappingComponent leftStickComponent; + private TheGamepadMappingComponent rightStickComponent; + private TheGamepadImagePanel imagePanel; + + public TheGamepadMappingPanel(JoystickModel model, TheGamepadImagePanel imagePanel) + { + this.model = model; + this.imagePanel = imagePanel; + GridBagLayout gridBagLayout = new GridBagLayout(); + gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 1.0}; + gridBagLayout.columnWeights = new double[]{1.0, 1.0}; + setLayout(gridBagLayout); + GridBagConstraints gbc_upComponent = new GridBagConstraints(); + gbc_upComponent.fill = GridBagConstraints.BOTH; + gbc_upComponent.gridx = 0; + gbc_upComponent.gridy = 0; + add(getUpComponent(), gbc_upComponent); + GridBagConstraints gbc_downgComponent = new GridBagConstraints(); + gbc_downgComponent.fill = GridBagConstraints.BOTH; + gbc_downgComponent.gridx = 0; + gbc_downgComponent.gridy = 1; + add(getDowngComponent(), gbc_downgComponent); + GridBagConstraints gbc_leftComponent = new GridBagConstraints(); + gbc_leftComponent.fill = GridBagConstraints.BOTH; + gbc_leftComponent.gridx = 0; + gbc_leftComponent.gridy = 2; + add(getMappingComponent_2(), gbc_leftComponent); + GridBagConstraints gbc_rightComponent = new GridBagConstraints(); + gbc_rightComponent.fill = GridBagConstraints.BOTH; + gbc_rightComponent.gridx = 0; + gbc_rightComponent.gridy = 3; + add(getRightComponent(), gbc_rightComponent); + GridBagConstraints gbc_xComponent = new GridBagConstraints(); + gbc_xComponent.fill = GridBagConstraints.BOTH; + gbc_xComponent.gridx = 1; + gbc_xComponent.gridy = 2; + add(getXComponent(), gbc_xComponent); + GridBagConstraints gbc_yComponent = new GridBagConstraints(); + gbc_yComponent.fill = GridBagConstraints.BOTH; + gbc_yComponent.gridx = 1; + gbc_yComponent.gridy = 3; + add(getYComponent(), gbc_yComponent); + GridBagConstraints gbc_aComponent = new GridBagConstraints(); + gbc_aComponent.fill = GridBagConstraints.BOTH; + gbc_aComponent.gridx = 1; + gbc_aComponent.gridy = 0; + add(getAComponent(), gbc_aComponent); + GridBagConstraints gbc_bComponent = new GridBagConstraints(); + gbc_bComponent.fill = GridBagConstraints.BOTH; + gbc_bComponent.gridx = 1; + gbc_bComponent.gridy = 1; + add(getBComponent(), gbc_bComponent); + GridBagConstraints gbc_leftTriggerComponent = new GridBagConstraints(); + gbc_leftTriggerComponent.fill = GridBagConstraints.BOTH; + gbc_leftTriggerComponent.gridx = 0; + gbc_leftTriggerComponent.gridy = 4; + add(getLeftTriggerComponent(), gbc_leftTriggerComponent); + GridBagConstraints gbc_rightTriggerComponent = new GridBagConstraints(); + gbc_rightTriggerComponent.fill = GridBagConstraints.BOTH; + gbc_rightTriggerComponent.gridx = 1; + gbc_rightTriggerComponent.gridy = 4; + add(getRightTriggerComponent(), gbc_rightTriggerComponent); + GridBagConstraints gbc_backGuideComponent = new GridBagConstraints(); + gbc_backGuideComponent.fill = GridBagConstraints.BOTH; + gbc_backGuideComponent.gridx = 0; + gbc_backGuideComponent.gridy = 5; + add(getBackGuideComponent(), gbc_backGuideComponent); + } + private TheGamepadMappingComponent getUpComponent() { + if (upComponent == null) { + upComponent = new TheGamepadMappingComponent(TheGamepadButton.UP, model, imagePanel); + } + return upComponent; + } + private TheGamepadMappingComponent getDowngComponent() { + if (downComponent == null) { + downComponent = new TheGamepadMappingComponent(TheGamepadButton.DOWN, model, imagePanel); + } + return downComponent; + } + private TheGamepadMappingComponent getMappingComponent_2() { + if (leftComponent == null) { + leftComponent = new TheGamepadMappingComponent(TheGamepadButton.LEFT, model, imagePanel); + } + return leftComponent; + } + private TheGamepadMappingComponent getRightComponent() { + if (rightComponent == null) { + rightComponent = new TheGamepadMappingComponent(TheGamepadButton.RIGHT, model, imagePanel); + } + return rightComponent; + } + private TheGamepadMappingComponent getXComponent() { + if (xComponent == null) { + xComponent = new TheGamepadMappingComponent(TheGamepadButton.X, model, imagePanel); + } + return xComponent; + } + private TheGamepadMappingComponent getYComponent() { + if (yComponent == null) { + yComponent = new TheGamepadMappingComponent(TheGamepadButton.Y, model, imagePanel); + } + return yComponent; + } + private TheGamepadMappingComponent getAComponent() { + if (aComponent == null) { + aComponent = new TheGamepadMappingComponent(TheGamepadButton.A, model, imagePanel); + } + return aComponent; + } + private TheGamepadMappingComponent getBComponent() { + if (bComponent == null) { + bComponent = new TheGamepadMappingComponent(TheGamepadButton.B, model, imagePanel); + } + return bComponent; + } + private TheGamepadMappingComponent getLeftTriggerComponent() { + if (leftTriggerComponent == null) { + leftTriggerComponent = new TheGamepadMappingComponent(TheGamepadButton.LSB, model, imagePanel); + } + return leftTriggerComponent; + } + private TheGamepadMappingComponent getRightTriggerComponent() { + if (rightTriggerComponent == null) { + rightTriggerComponent = new TheGamepadMappingComponent(TheGamepadButton.RSB, model, imagePanel); + } + return rightTriggerComponent; + } + private TheGamepadMappingComponent getBackGuideComponent() { + if (backGuideComponent == null) { + backGuideComponent = new TheGamepadMappingComponent(TheGamepadButton.MENU, model, imagePanel); + } + return backGuideComponent; + } +} diff --git a/src/main/java/se/lantz/gui/gamepad/USBControllerBackgroundPanel.java b/src/main/java/se/lantz/gui/gamepad/USBControllerBackgroundPanel.java new file mode 100644 index 0000000..21eda73 --- /dev/null +++ b/src/main/java/se/lantz/gui/gamepad/USBControllerBackgroundPanel.java @@ -0,0 +1,66 @@ +package se.lantz.gui.gamepad; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JPanel; + +import se.lantz.model.JoystickModel; + +public class USBControllerBackgroundPanel extends JPanel +{ + private USBControllerInfoPanel gamePadInfoPanel; + private USBControllerImagePanel gamePadImagePanel; + private USBControllerMappingPanel gamePadMappingPanel; + private JoystickModel model; + public USBControllerBackgroundPanel(JoystickModel model) { + this.model = model; + GridBagLayout gridBagLayout = new GridBagLayout(); + setLayout(gridBagLayout); + GridBagConstraints gbc_gamePadInfoPanel = new GridBagConstraints(); + gbc_gamePadInfoPanel.gridwidth = 2; + gbc_gamePadInfoPanel.insets = new Insets(0, 0, 5, 0); + gbc_gamePadInfoPanel.anchor = GridBagConstraints.NORTHWEST; + gbc_gamePadInfoPanel.weightx = 1.0; + gbc_gamePadInfoPanel.fill = GridBagConstraints.BOTH; + gbc_gamePadInfoPanel.gridx = 0; + gbc_gamePadInfoPanel.gridy = 0; + add(getGamePadInfoPanel(), gbc_gamePadInfoPanel); + GridBagConstraints gbc_gamePadImagePanel = new GridBagConstraints(); + gbc_gamePadImagePanel.anchor = GridBagConstraints.NORTHWEST; + gbc_gamePadImagePanel.insets = new Insets(0, 0, 5, 10); + gbc_gamePadImagePanel.weightx = 1.0; + gbc_gamePadImagePanel.fill = GridBagConstraints.BOTH; + gbc_gamePadImagePanel.gridx = 1; + gbc_gamePadImagePanel.gridy = 1; + add(getGamePadImagePanel(), gbc_gamePadImagePanel); + GridBagConstraints gbc_gamePadMappingPanel = new GridBagConstraints(); + gbc_gamePadMappingPanel.insets = new Insets(0, 10, 0, 0); + gbc_gamePadMappingPanel.weighty = 1.0; + gbc_gamePadMappingPanel.weightx = 1.0; + gbc_gamePadMappingPanel.anchor = GridBagConstraints.NORTHWEST; + gbc_gamePadMappingPanel.fill = GridBagConstraints.BOTH; + gbc_gamePadMappingPanel.gridx = 0; + gbc_gamePadMappingPanel.gridy = 1; + add(getGamePadMappingPanel(), gbc_gamePadMappingPanel); + } + private USBControllerInfoPanel getGamePadInfoPanel() { + if (gamePadInfoPanel == null) { + gamePadInfoPanel = new USBControllerInfoPanel(); + } + return gamePadInfoPanel; + } + private USBControllerImagePanel getGamePadImagePanel() { + if (gamePadImagePanel == null) { + gamePadImagePanel = new USBControllerImagePanel(); + } + return gamePadImagePanel; + } + private USBControllerMappingPanel getGamePadMappingPanel() { + if (gamePadMappingPanel == null) { + gamePadMappingPanel = new USBControllerMappingPanel(model, getGamePadImagePanel()); + } + return gamePadMappingPanel; + } +} diff --git a/src/main/java/se/lantz/gui/gamepad/GamePadImagePanel.java b/src/main/java/se/lantz/gui/gamepad/USBControllerImagePanel.java similarity index 92% rename from src/main/java/se/lantz/gui/gamepad/GamePadImagePanel.java rename to src/main/java/se/lantz/gui/gamepad/USBControllerImagePanel.java index a732bf6..0b31547 100644 --- a/src/main/java/se/lantz/gui/gamepad/GamePadImagePanel.java +++ b/src/main/java/se/lantz/gui/gamepad/USBControllerImagePanel.java @@ -17,9 +17,9 @@ import javax.swing.JPanel; import se.lantz.util.FileManager; -public class GamePadImagePanel extends JPanel +public class USBControllerImagePanel extends JPanel { - public enum GamePadButton + public enum USBControllerButton { UP("Up", Character.toString(0x1f815)), DOWN("Down", Character.toString(0x1f817)), LEFT("Left", Character.toString(0x1f814)), RIGHT("Right", Character.toString(0x1f816)), A("A", "A"), B("B", "B"), @@ -30,7 +30,7 @@ public class GamePadImagePanel extends JPanel public final String label; public final String joyMapping; - private GamePadButton(String label, String joyMapping) + private USBControllerButton(String label, String joyMapping) { this.label = label; this.joyMapping = joyMapping; @@ -40,9 +40,9 @@ public class GamePadImagePanel extends JPanel ImageIcon gamepadImage = new ImageIcon(getClass().getResource("/se/lantz/logitech.png")); private JLabel imageLabel; - private GamePadButton currentButton = null; + private USBControllerButton currentButton = null; - public GamePadImagePanel() + public USBControllerImagePanel() { GridBagLayout gridBagLayout = new GridBagLayout(); setLayout(gridBagLayout); @@ -77,7 +77,7 @@ public class GamePadImagePanel extends JPanel return imageLabel; } - public void setCurrentButtonAndRepaint(GamePadButton button) + public void setCurrentButtonAndRepaint(USBControllerButton button) { this.currentButton = button; this.repaint(); diff --git a/src/main/java/se/lantz/gui/gamepad/GamePadInfoPanel.java b/src/main/java/se/lantz/gui/gamepad/USBControllerInfoPanel.java similarity index 97% rename from src/main/java/se/lantz/gui/gamepad/GamePadInfoPanel.java rename to src/main/java/se/lantz/gui/gamepad/USBControllerInfoPanel.java index 9cbef98..48ce4f4 100644 --- a/src/main/java/se/lantz/gui/gamepad/GamePadInfoPanel.java +++ b/src/main/java/se/lantz/gui/gamepad/USBControllerInfoPanel.java @@ -11,7 +11,7 @@ import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.Color; -public class GamePadInfoPanel extends JPanel +public class USBControllerInfoPanel extends JPanel { ImageIcon compImage = new ImageIcon(getClass().getResource("/se/lantz/joystick-comp.png")); @@ -19,7 +19,7 @@ public class GamePadInfoPanel extends JPanel private JLabel compImageLabel; private JLabel extraButtonsInfoLabel; - public GamePadInfoPanel() + public USBControllerInfoPanel() { setBackground(Color.WHITE); GridBagLayout gridBagLayout = new GridBagLayout(); diff --git a/src/main/java/se/lantz/gui/gamepad/MappingComponent.java b/src/main/java/se/lantz/gui/gamepad/USBControllerMappingComponent.java similarity index 93% rename from src/main/java/se/lantz/gui/gamepad/MappingComponent.java rename to src/main/java/se/lantz/gui/gamepad/USBControllerMappingComponent.java index 3d29c35..4412936 100644 --- a/src/main/java/se/lantz/gui/gamepad/MappingComponent.java +++ b/src/main/java/se/lantz/gui/gamepad/USBControllerMappingComponent.java @@ -16,19 +16,19 @@ import javax.swing.JPanel; import javax.swing.SwingUtilities; import se.lantz.gui.KeySelectionComboBox; -import se.lantz.gui.gamepad.GamePadImagePanel.GamePadButton; +import se.lantz.gui.gamepad.USBControllerImagePanel.USBControllerButton; import se.lantz.model.JoystickModel; -public class MappingComponent extends JPanel +public class USBControllerMappingComponent extends JPanel { private JLabel buttonTextLabel; private KeySelectionComboBox keySelectionComboBox; private JLabel joyMapLabel; - private GamePadButton button; + private USBControllerButton button; private JoystickModel model; - private GamePadImagePanel imagePanel; + private USBControllerImagePanel imagePanel; - public MappingComponent(GamePadButton button, JoystickModel model, GamePadImagePanel imagePanel) + public USBControllerMappingComponent(USBControllerButton button, JoystickModel model, USBControllerImagePanel imagePanel) { this.button = button; this.model = model; @@ -193,7 +193,7 @@ public class MappingComponent extends JPanel Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (focusOwner instanceof KeySelectionComboBox) { - MappingComponent focusedMappingComponent = (MappingComponent)SwingUtilities.getAncestorOfClass(MappingComponent.class, focusOwner); + USBControllerMappingComponent focusedMappingComponent = (USBControllerMappingComponent)SwingUtilities.getAncestorOfClass(USBControllerMappingComponent.class, focusOwner); if (focusedMappingComponent != null) { imagePanel.setCurrentButtonAndRepaint(focusedMappingComponent.button); diff --git a/src/main/java/se/lantz/gui/gamepad/GamePadMappingPanel.java b/src/main/java/se/lantz/gui/gamepad/USBControllerMappingPanel.java similarity index 60% rename from src/main/java/se/lantz/gui/gamepad/GamePadMappingPanel.java rename to src/main/java/se/lantz/gui/gamepad/USBControllerMappingPanel.java index 489d610..234303a 100644 --- a/src/main/java/se/lantz/gui/gamepad/GamePadMappingPanel.java +++ b/src/main/java/se/lantz/gui/gamepad/USBControllerMappingPanel.java @@ -3,32 +3,32 @@ package se.lantz.gui.gamepad; import java.awt.GridBagLayout; import javax.swing.JPanel; -import se.lantz.gui.gamepad.GamePadImagePanel.GamePadButton; +import se.lantz.gui.gamepad.USBControllerImagePanel.USBControllerButton; import se.lantz.model.JoystickModel; import java.awt.GridBagConstraints; import java.awt.Insets; -public class GamePadMappingPanel extends JPanel +public class USBControllerMappingPanel extends JPanel { - private MappingComponent upComponent; + private USBControllerMappingComponent upComponent; private JoystickModel model; - private MappingComponent downComponent; - private MappingComponent leftComponent; - private MappingComponent rightComponent; - private MappingComponent xComponent; - private MappingComponent yComponent; - private MappingComponent aComponent; - private MappingComponent bComponent; - private MappingComponent leftTriggerComponent; - private MappingComponent rightTriggerComponent; - private MappingComponent backGuideComponent; - private MappingComponent leftShoulderComponent; - private MappingComponent rightShoulderComponent; - private MappingComponent leftStickComponent; - private MappingComponent rightStickComponent; - private GamePadImagePanel imagePanel; + private USBControllerMappingComponent downComponent; + private USBControllerMappingComponent leftComponent; + private USBControllerMappingComponent rightComponent; + private USBControllerMappingComponent xComponent; + private USBControllerMappingComponent yComponent; + private USBControllerMappingComponent aComponent; + private USBControllerMappingComponent bComponent; + private USBControllerMappingComponent leftTriggerComponent; + private USBControllerMappingComponent rightTriggerComponent; + private USBControllerMappingComponent backGuideComponent; + private USBControllerMappingComponent leftShoulderComponent; + private USBControllerMappingComponent rightShoulderComponent; + private USBControllerMappingComponent leftStickComponent; + private USBControllerMappingComponent rightStickComponent; + private USBControllerImagePanel imagePanel; - public GamePadMappingPanel(JoystickModel model, GamePadImagePanel imagePanel) + public USBControllerMappingPanel(JoystickModel model, USBControllerImagePanel imagePanel) { this.model = model; this.imagePanel = imagePanel; @@ -114,93 +114,93 @@ public class GamePadMappingPanel extends JPanel gbc_rightStickComponent.gridy = 7; add(getRightStickComponent(), gbc_rightStickComponent); } - private MappingComponent getUpComponent() { + private USBControllerMappingComponent getUpComponent() { if (upComponent == null) { - upComponent = new MappingComponent(GamePadButton.UP, model, imagePanel); + upComponent = new USBControllerMappingComponent(USBControllerButton.UP, model, imagePanel); } return upComponent; } - private MappingComponent getDowngComponent() { + private USBControllerMappingComponent getDowngComponent() { if (downComponent == null) { - downComponent = new MappingComponent(GamePadButton.DOWN, model, imagePanel); + downComponent = new USBControllerMappingComponent(USBControllerButton.DOWN, model, imagePanel); } return downComponent; } - private MappingComponent getMappingComponent_2() { + private USBControllerMappingComponent getMappingComponent_2() { if (leftComponent == null) { - leftComponent = new MappingComponent(GamePadButton.LEFT, model, imagePanel); + leftComponent = new USBControllerMappingComponent(USBControllerButton.LEFT, model, imagePanel); } return leftComponent; } - private MappingComponent getRightComponent() { + private USBControllerMappingComponent getRightComponent() { if (rightComponent == null) { - rightComponent = new MappingComponent(GamePadButton.RIGHT, model, imagePanel); + rightComponent = new USBControllerMappingComponent(USBControllerButton.RIGHT, model, imagePanel); } return rightComponent; } - private MappingComponent getXComponent() { + private USBControllerMappingComponent getXComponent() { if (xComponent == null) { - xComponent = new MappingComponent(GamePadButton.X, model, imagePanel); + xComponent = new USBControllerMappingComponent(USBControllerButton.X, model, imagePanel); } return xComponent; } - private MappingComponent getYComponent() { + private USBControllerMappingComponent getYComponent() { if (yComponent == null) { - yComponent = new MappingComponent(GamePadButton.Y, model, imagePanel); + yComponent = new USBControllerMappingComponent(USBControllerButton.Y, model, imagePanel); } return yComponent; } - private MappingComponent getAComponent() { + private USBControllerMappingComponent getAComponent() { if (aComponent == null) { - aComponent = new MappingComponent(GamePadButton.A, model, imagePanel); + aComponent = new USBControllerMappingComponent(USBControllerButton.A, model, imagePanel); } return aComponent; } - private MappingComponent getBComponent() { + private USBControllerMappingComponent getBComponent() { if (bComponent == null) { - bComponent = new MappingComponent(GamePadButton.B, model, imagePanel); + bComponent = new USBControllerMappingComponent(USBControllerButton.B, model, imagePanel); } return bComponent; } - private MappingComponent getLeftTriggerComponent() { + private USBControllerMappingComponent getLeftTriggerComponent() { if (leftTriggerComponent == null) { - leftTriggerComponent = new MappingComponent(GamePadButton.LEFT_TRIGGER, model, imagePanel); + leftTriggerComponent = new USBControllerMappingComponent(USBControllerButton.LEFT_TRIGGER, model, imagePanel); } return leftTriggerComponent; } - private MappingComponent getRightTriggerComponent() { + private USBControllerMappingComponent getRightTriggerComponent() { if (rightTriggerComponent == null) { - rightTriggerComponent = new MappingComponent(GamePadButton.RIGHT_TRIGGER, model, imagePanel); + rightTriggerComponent = new USBControllerMappingComponent(USBControllerButton.RIGHT_TRIGGER, model, imagePanel); } return rightTriggerComponent; } - private MappingComponent getBackGuideComponent() { + private USBControllerMappingComponent getBackGuideComponent() { if (backGuideComponent == null) { - backGuideComponent = new MappingComponent(GamePadButton.BACK_GUIDE, model, imagePanel); + backGuideComponent = new USBControllerMappingComponent(USBControllerButton.BACK_GUIDE, model, imagePanel); } return backGuideComponent; } - private MappingComponent getLeftShoulderComponent() { + private USBControllerMappingComponent getLeftShoulderComponent() { if (leftShoulderComponent == null) { - leftShoulderComponent = new MappingComponent(GamePadButton.LEFT_SHOULDER, model, imagePanel); + leftShoulderComponent = new USBControllerMappingComponent(USBControllerButton.LEFT_SHOULDER, model, imagePanel); } return leftShoulderComponent; } - private MappingComponent getRightShoulderComponent() { + private USBControllerMappingComponent getRightShoulderComponent() { if (rightShoulderComponent == null) { - rightShoulderComponent = new MappingComponent(GamePadButton.RIGHT_SHOULDER, model, imagePanel); + rightShoulderComponent = new USBControllerMappingComponent(USBControllerButton.RIGHT_SHOULDER, model, imagePanel); } return rightShoulderComponent; } - private MappingComponent getLeftStickComponent() { + private USBControllerMappingComponent getLeftStickComponent() { if (leftStickComponent == null) { - leftStickComponent = new MappingComponent(GamePadButton.LEFT_STICK, model, imagePanel); + leftStickComponent = new USBControllerMappingComponent(USBControllerButton.LEFT_STICK, model, imagePanel); } return leftStickComponent; } - private MappingComponent getRightStickComponent() { + private USBControllerMappingComponent getRightStickComponent() { if (rightStickComponent == null) { - rightStickComponent = new MappingComponent(GamePadButton.RIGHT_STICK, model, imagePanel); + rightStickComponent = new USBControllerMappingComponent(USBControllerButton.RIGHT_STICK, model, imagePanel); } return rightStickComponent; } diff --git a/src/main/resources/se/lantz/TheGamepad.png b/src/main/resources/se/lantz/TheGamepad.png new file mode 100644 index 0000000000000000000000000000000000000000..f24bfb66871f2a84878451b5451b3b9ebbf5d8a2 GIT binary patch literal 42961 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 OmX^AnTBC|X^#1@+v~pDd literal 0 HcmV?d00001 diff --git a/src/main/resources/se/lantz/TheGamepadMapping.png b/src/main/resources/se/lantz/TheGamepadMapping.png new file mode 100644 index 0000000000000000000000000000000000000000..fa428a758dc84178d31a29095b25bbd9f42aca35 GIT binary patch literal 4098 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 J)+yP%`!@@uywm^y literal 0 HcmV?d00001