How to add a scrollbar for long JComponents in a JPanel? How to center a JComponent?

ε祈祈猫儿з 提交于 2019-12-11 01:43:56

问题


Currently, I have to JComponents contained in a JPanel with a vertical box layout. This way, I can have the first component centered, as shown below, and have the bottom component (which is quite long) below. However, since the bottom component is very long I wanted to add a slider just for that specific component. This way, the user can see all of the bottom component with the upper component remaining centered. However, my code below doesn't fix anything and the scrollbar never even works. The only information about GPComponent and GPinfinity you need to know is they override the preferredSize, minimumSize, maximumSize, and paintComponent methods (they extend JComponent).

JFrame frame = new JFrame();
JPanel panel = new JPanel();

GPComponent gp = new GPComponent(n, k);
GPinfinityComponent gpi = new GPinfinityComponent(n, k);

Box box = new Box(BoxLayout.Y_AXIS);

panel.add(Box.createVerticalGlue());
panel.add(gp);
panel.add(Box.createVerticalGlue());
JScrollPane thePane = new JScrollPane(gpi, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    panel.add(thePane);

frame.pack();6
frame.add(panel, BorderLayout.CENTER); // just to be clear
frame.setVisible(true);
final int FRAME_WIDTH = 600;
final int FRAME_HEIGHT = 600;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("GP("+n+", "+k+")");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

Also: the maximumSize=minimumSize=preferredSize for both components For the circular one the dimensions are (350, 350) and for the other the dimensions are (5000, 150).


回答1:


You state:

...and for the other the dimensions are (5000, 150).

If this is the component that is supposed to show the scrollbars, the Java is telling you otherwise, that it is in fact much shorter than you suppose it to be. I wonder if you're setting size instead of preferredSize. You actually should not be setting either but rather should override getPreferredSize() and have it return a dimension appropriate for the component.

For more detailed help, consider creating and posting a minimal example program.


Edit
For example, my MCVE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;

import javax.swing.*;

@SuppressWarnings("serial")
public class PreferredSizeEg extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;

   public PreferredSizeEg() {
      JPanel centerPanel = new JPanel(new GridBagLayout());
      centerPanel.add(new CenterImagePanel());

      JScrollPane scrollpane = new JScrollPane(new LongImagePanel(),
            JScrollPane.VERTICAL_SCROLLBAR_NEVER,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

      setLayout(new BorderLayout());
      add(centerPanel, BorderLayout.CENTER);
      add(scrollpane, BorderLayout.PAGE_END);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class LongImagePanel extends JPanel {
      private static final int LI_PREF_W = 5000;
      private static final int LI_PREF_H = 150;

      @Override
      protected void paintComponent(Graphics g) {
         super.paintComponent(g);
         Graphics2D g2 = (Graphics2D) g;
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);

         int index = 0;
         int spriteWidth = 50;
         while ((index) * spriteWidth < getWidth()) {
            Color c = index % 2 == 0 ? Color.green : Color.red;
            g.setColor(c);
            int x = 2 + index * spriteWidth;
            int y = 2;
            int width = getHeight() - 4;
            int height = width;
            g.fillOval(x, y, width, height);
            index++;
         }
      }

      @Override
      public Dimension getPreferredSize() {
         return new Dimension(LI_PREF_W, LI_PREF_H);
      }
   }

   private class CenterImagePanel extends JPanel {
      private static final int CIP_PREF_W = 200;
      private static final int CIP_PREF_H = CIP_PREF_W;

      public CenterImagePanel() {
         setBorder(BorderFactory.createLineBorder(Color.BLACK));
      }

      @Override
      protected void paintComponent(Graphics g) {
         super.paintComponent(g);
         Graphics2D g2 = (Graphics2D) g;
         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
         g.setColor(Color.green);
         int x = 5;
         int y = x;
         int width = getWidth() - 2 * x;
         int height = getHeight() - 2 * y;
         g.fillOval(x, y, width, height);
      }

      @Override
      public Dimension getPreferredSize() {
         return new Dimension(CIP_PREF_W, CIP_PREF_H);
      }
   }

   private static void createAndShowGui() {
      PreferredSizeEg mainPanel = new PreferredSizeEg();

      JFrame frame = new JFrame("PreferredSizeEg");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Which displays as:



来源:https://stackoverflow.com/questions/24770777/how-to-add-a-scrollbar-for-long-jcomponents-in-a-jpanel-how-to-center-a-jcompon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!