Add a complex image in the panel, with buttons around it in one customized user interface
Asked Answered
M

3

21

How can i have this image like below into the slavePanel and on top of that JPanel adjust the JButtons which looks like the image but having buttons correctly wrapped around? (Right now they are shaped in 1 row, 4 column)

enter image description here

  //
  // Shot Gun mover up/down/left/right, middle on is for zoom
  //
  public void GunMover(JPanel configPanel) throws IOException {

    // Master Panel - holds everything
    JPanel masterPanel = new Panel();
    masterPanel.setLayout(new SpringLayout());

    // Slave Panel - with image background 
    JPanel slavePanel = new Panel();
    slavePanel.setLayout(new SpringLayout());

    // Row 1
    final JButton ptzLeft = new JButton("<");       
    masterPanel.add(ptzLeft, BorderLayout.WEST);

    // Row 2
    final JButton ptzRight = new JButton(">");   
    masterPanel.add(ptzRight, BorderLayout.CENTER);    

    // Row 3
    final JButton ptzUp = new JButton("^");   
    masterPanel.add(ptzUp, BorderLayout.WEST);    

    // Row 4
    final JButton ptzDown = new JButton("down");   
    masterPanel.add(ptzDown, BorderLayout.CENTER);    

    // How do i add slavePanel this background and add all the JButtons 
    // According to that image shape?

    // Layout the panel.
    SpringUtilities.makeCompactGrid(masterPanel,
                                1, 4, //rows, cols
                                6, 6, //initX, initY
                                6, 6);        

    configPanel.setLayout(new GridLayout(0,1));
    configPanel.add(masterPanel);   
  }

Follow up: Excellent one from Andrew Thompson + at-least my broken method

enter image description here

package test;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import javax.swing.*;

public class New extends JFrame {

  private static final long serialVersionUID = 1L;
  private ImageIcon errorIcon =
          (ImageIcon) UIManager.getIcon("OptionPane.errorIcon");
  private Icon infoIcon =
          UIManager.getIcon("OptionPane.informationIcon");
  private Icon warnIcon =
          UIManager.getIcon("OptionPane.warningIcon");

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        New t = new New();
      }
    });
  }

  public New() {
    setLayout(new BorderLayout());

    JPanel slavePanel = new NewPanel();
    slavePanel.setLayout(new GridLayout(0, 2, 4, 4));
    add(slavePanel);    

    JButton button = new JButton();
    button.setBorderPainted(false);
    button.setBorder(null);
    button.setFocusable(false);
    button.setMargin(new Insets(0, 0, 0, 0));
    button.setContentAreaFilled(false);
    button.setIcon((errorIcon));
    button.setRolloverIcon((infoIcon));
    button.setPressedIcon(warnIcon);
    button.setDisabledIcon(warnIcon);
    slavePanel.add(button);    

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setVisible(true);
  }
}


package test;

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;

public class NewPanel extends JPanel {

  private Image imageGui;
  private static Dimension screen;

  public NewPanel() {
    try {
      imageGui =
              ImageIO.read(
              (InputStream) NewPanel.class.getResourceAsStream(
              "/image/ptz.png"));
    } catch (IOException e) {
      e.printStackTrace(System.err);
    }

    Border border = BorderFactory.createEmptyBorder(11, 11, 11, 11);
    setOpaque(true);
    setBorder(border);
    setFocusable(true);
    setSize(getPreferredSize());
    revalidate();
    repaint();
    setVisible(true);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(imageGui, 0, 0,
            imageGui.getWidth(null), imageGui.getHeight(null), null);
    revalidate();
    repaint();
  }

  @Override
  public Dimension getPreferredSize() {
    return new Dimension(imageGui.getWidth(null), imageGui.getHeight(null));
  }
}
Malek answered 2/6, 2012 at 11:13 Comment(0)
D
20
  1. Use a 3x3 GridLayout
  2. For each of the 9 cells get a subimage:
  • For every second component, add a label with the subimage.
  • For every other component, add a JButton from which the space is removed. Use the subimage as icon, but you'll need alternate icons to indicate focus, activation etc. This example puts a red border around the 'pressed' icon.

Compass Buttons

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.URL;
import javax.imageio.ImageIO;

public class CompassButtons {

    public CompassButtons(BufferedImage bi) {
        int w = bi.getWidth();
        int h = bi.getHeight();
        int step = w / 3;
        JPanel p = new JPanel(new GridLayout(3, 3));
        p.setBackground(Color.BLACK);
        int count = 0;
        for (int ii = 0; ii < w; ii += step) {
            for (int jj = 0; jj < h; jj += step) {
                // This is it - GET THE SUB IMAGE
                Image icon = bi.getSubimage(jj, ii, step, step);
                if (count % 2 == 1) {
                    JButton button = new JButton(new ImageIcon(icon));

                    // make it transparent
                    button.setContentAreaFilled(false);

                    // remove border, indicate press using different icon
                    button.setBorder(null);

                    // make a 'pressed' icon..
                    BufferedImage iconPressed = new BufferedImage(
                            step, step, BufferedImage.TYPE_INT_ARGB);
                    Graphics g = iconPressed.getGraphics();
                    g.drawImage(icon, 0, 0, p);
                    g.setColor(Color.RED);
                    g.drawRoundRect(
                            0, 0,
                            iconPressed.getWidth(p) - 1, 
                            iconPressed.getHeight(p) - 1,
                            12, 12);
                    g.dispose();
                    button.setPressedIcon(new ImageIcon(iconPressed));

                    button.setActionCommand("" + count);
                    button.addActionListener((ActionEvent ae) -> {
                        System.out.println(ae.getActionCommand());
                    });

                    p.add(button);
                } else {
                    JLabel label = new JLabel(new ImageIcon(icon));
                    p.add(label);
                }
                count++;
            }
        }
        JPanel center = new JPanel(new GridBagLayout());
        center.setBackground(Color.BLACK);
        center.add(p);
        JOptionPane.showMessageDialog(null, center);
    }

    public static void main(String[] args) throws Exception {
        URL url = new URL("https://i.sstatic.net/SNN04.png");
        final BufferedImage bi = ImageIO.read(url);
        SwingUtilities.invokeLater(() -> {
            new CompassButtons(bi);
        });
    }
}
Directed answered 2/6, 2012 at 12:16 Comment(3)
This one is so cool. May I ask what does button.setActionCommand("" + count); do? Oracle java doc only explain: Sets the action command for this button. But now I have no idea what does Action command mean.....Negro
@JianHe It is passed to the ActionEvent created, and can be accessed via ActionEvent.getActionCommand(). We could alternately use ActionEvent.getSource() to find the source component (like a JButton). But more commonly we create an ActionListener (or Action - e.g. a saveEditsAction) for a particular control (or controls - like both a button and menu) and then getting either the action command or the source component becomes irrelevant. I used the action command in a single action listener in that example to make the code shorter and show the button 'number' in the console.Directed
through this (#8215458). I got it. Thanks. Now I totally understand it.Negro
L
3

1) you have to prepare the Icons before and for every 5 JButtons (event here came from ButtonModel)

  • basic Icon without Focus

  • Icon for isRollover()

  • Icon for isPressed()

2) how to set Icons and to remove all "balast" from JButton

3) put these 5 JButtons to the JPanel with painted circles (RemoteSet)

Lorenz answered 2/6, 2012 at 11:24 Comment(4)
"every 5 JButtons" 5 buttons? I get N/S/E/W for 4 - but which is the 5th button?Directed
@Andrew Thompson which is the 5th button? eeeehmmm == Enter Key in the middle in the CENTER area(Panasonics Remotes has similair design)Lorenz
Thank you. Edited above, middle one is not important was hard to find up/down/left/right, which is nicely working.Malek
@YumYumYum heheh nothing complicated, great answerers (excluding my person) in this thread, isn't itLorenz
P
3

Starting from this example, I got a start by changing MoveButton like this:

this.setBorderPainted(false);

You could give ControlPanel a Custom Layout Manager. I'd also add a background image and some kind of visual feedback based on the ButtonModel state, as suggested here.

Perception answered 2/6, 2012 at 11:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.