How do I make my custom Swing component visible?

后端 未结 2 523
孤城傲影
孤城傲影 2020-12-11 23:48

I have no idea why it won\'t show. First I create an instance of the component and then add it to a certain element in a two-dimensional JPanel array. Then I loop through th

相关标签:
2条回答
  • 2020-12-12 00:21

    I tried extending JPanel instead, got a small 10x10 pix gray box under my menu. Atleast a start

    When you use a JComponent the preferred size is (0, 0) which is why you see nothing.

    When you use a JPanel is uses a FlowLayout by default and the FlowLayout has a 5 pixel gap before/after each component added to the panel. Since you don't add any components the preffered size is just the gap so you get a size of (10, 10).

    Therefore, when you do custom painting you need to override the getPreferredSize() method to return a proper value for the custom painting you intend to implement.

    Edit:

    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    
    public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener
    {
        JLayeredPane layeredPane;
        JPanel chessBoard;
        JLabel chessPiece;
        int xAdjustment;
        int yAdjustment;
    
        public ChessBoard()
        {
            Dimension boardSize = new Dimension(600, 600);
    
            //  Use a Layered Pane for this this application
    
            layeredPane = new JLayeredPane();
            layeredPane.setPreferredSize( boardSize );
            layeredPane.addMouseListener( this );
            layeredPane.addMouseMotionListener( this );
            getContentPane().add(layeredPane);
    
            //  Add a chess board to the Layered Pane
    
            chessBoard = new JPanel();
            chessBoard.setLayout( new GridLayout(8, 8) );
            chessBoard.setPreferredSize( boardSize );
            chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
            layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
    
            //  Build the Chess Board squares
    
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    JPanel square = new JPanel( new BorderLayout() );
                    square.setBackground( (i + j) % 2 == 0 ? Color.red : Color.white );
                    chessBoard.add( square );
                }
            }
    
            // Add a few pieces to the board
    
            ImageIcon duke = new ImageIcon("dukewavered.gif"); // add an image here
    
            JLabel piece = new JLabel( duke );
            JPanel panel = (JPanel)chessBoard.getComponent( 0 );
            panel.add( piece );
            piece = new JLabel( duke );
            panel = (JPanel)chessBoard.getComponent( 15 );
            panel.add( piece );
        }
    
        /*
        **  Add the selected chess piece to the dragging layer so it can be moved
        */
        public void mousePressed(MouseEvent e)
        {
            chessPiece = null;
            Component c =  chessBoard.findComponentAt(e.getX(), e.getY());
    
            if (c instanceof JPanel) return;
    
            Point parentLocation = c.getParent().getLocation();
            xAdjustment = parentLocation.x - e.getX();
            yAdjustment = parentLocation.y - e.getY();
            chessPiece = (JLabel)c;
            chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
    
            layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
            layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
        }
    
        /*
        **  Move the chess piece around
        */
        public void mouseDragged(MouseEvent me)
        {
            if (chessPiece == null) return;
    
            //  The drag location should be within the bounds of the chess board
    
            int x = me.getX() + xAdjustment;
            int xMax = layeredPane.getWidth() - chessPiece.getWidth();
            x = Math.min(x, xMax);
            x = Math.max(x, 0);
    
            int y = me.getY() + yAdjustment;
            int yMax = layeredPane.getHeight() - chessPiece.getHeight();
            y = Math.min(y, yMax);
            y = Math.max(y, 0);
    
            chessPiece.setLocation(x, y);
         }
    
        /*
        **  Drop the chess piece back onto the chess board
        */
        public void mouseReleased(MouseEvent e)
        {
            layeredPane.setCursor(null);
    
            if (chessPiece == null) return;
    
            //  Make sure the chess piece is no longer painted on the layered pane
    
            chessPiece.setVisible(false);
            layeredPane.remove(chessPiece);
            chessPiece.setVisible(true);
    
            //  The drop location should be within the bounds of the chess board
    
            int xMax = layeredPane.getWidth() - chessPiece.getWidth();
            int x = Math.min(e.getX(), xMax);
            x = Math.max(x, 0);
    
            int yMax = layeredPane.getHeight() - chessPiece.getHeight();
            int y = Math.min(e.getY(), yMax);
            y = Math.max(y, 0);
    
            Component c =  chessBoard.findComponentAt(x, y);
    
            if (c instanceof JLabel)
            {
                Container parent = c.getParent();
                parent.remove(0);
                parent.add( chessPiece );
                parent.validate();
            }
            else
            {
                Container parent = (Container)c;
                parent.add( chessPiece );
                parent.validate();
            }
        }
    
        public void mouseClicked(MouseEvent e) {}
        public void mouseMoved(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
    
        public static void main(String[] args)
        {
            JFrame frame = new ChessBoard();
            frame.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
            frame.setResizable( false );
            frame.pack();
            frame.setLocationRelativeTo( null );
            frame.setVisible(true);
         }
    }
    
    0 讨论(0)
  • 2020-12-12 00:23

    In the past, I have solved this by extending JPanel instead of JComponent. I found an good example here. Here's an adaptation of it which will draw a box:

    public class Box extends JPanel {
      Color color;
    
      public Box (Color c, int w, int h) {
        color = color;
        setSize(w, h);
      }
    
      @Override
      public void paintComponent(Graphics g) {
        g.setColor(color);
        g.drawOval(0, 0, getWidth(), getHeight());
     }
    
     ...
    

    This isn't exactly like your code above, but hopefully it'll get you started in the right direction!

    A quick note (original response): the example above View is a JFrame which is never made visible. Instead, the class variable gameWindow is used. It would be good practice to make the top-level class the visible window.

    0 讨论(0)
提交回复
热议问题