Как добавить полосу прокрутки для длинных JComponents в JPanel? Как центрировать JComponent?

В настоящее время у меня есть JComponents, содержащиеся в JPanel с вертикальной компоновкой. Таким образом, я могу расположить первый компонент по центру, как показано ниже, а нижний компонент (который довольно длинный) расположить ниже. Однако, поскольку нижний компонент очень длинный, я хотел добавить ползунок только для этого конкретного компонента. Таким образом, пользователь может видеть весь нижний компонент, а верхний компонент остается в центре. Однако мой код ниже ничего не исправляет, и полоса прокрутки даже не работает. Единственная информация о GPComponent и GPinfinity, которую вам нужно знать, это то, что они переопределяют методы PreferredSize, MinimumSize, MaximumSize и paintComponent (они расширяют 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);

Также: максимальный размер=минимальный размер=предпочтительный размер для обоих компонентов. Для круглого компонента размеры (350, 350), а для другого - (5000, 150).


person user2154420    schedule 16.07.2014    source источник
comment
I have to JComponents contained in a JPanel with a vertical box layout. не основано на опубликованном вами коде. Вы создаете Box, но затем добавляете все компоненты на панель, которая использует FlowLayout. Компоненты просто обертываются, поэтому создается впечатление, что вы используете Box.   -  person camickr    schedule 16.07.2014


Ответы (1)


Вы заявляете:

... а для другого размеры (5000, 150).

Если это компонент, который должен отображать полосы прокрутки, Java говорит вам об обратном, что на самом деле он намного короче, чем вы предполагаете. Интересно, устанавливаете ли вы размер вместо предпочитаемого размера. На самом деле вы также не должны устанавливать, а скорее должны переопределить getPreferredSize() и вернуть размер, соответствующий компоненту.

Для получения более подробной справки рассмотрите возможность создания и публикации минимального примера программы.


Изменить
Например, мой 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();
         }
      });
   }
}

Что отображается как:

введите здесь описание изображения

person Hovercraft Full Of Eels    schedule 16.07.2014
comment
+1, Всегда полезно переопределить getPreferredSize() и всегда полезно опубликовать правильный MCVE (SSCCE) с вопросом. Возможно, проблема просто в том, что у вас опечатка. Возможно, вы использовали 500 вместо 5000 для предпочтительного размера. Вы должны установить какое-то значение, так как компонент появляется, а FlowLayout всегда учитывает предпочтительный размер компонента. - person camickr; 16.07.2014
comment
Я заставил его работать после изменения всех моих макетов на упомянутые выше... макеты все еще кажутся очень сложными... - person user2154420; 16.07.2014
comment
@ user2154420: Как и все остальное, их становится проще использовать, чем больше вы их используете, тем лучше вы с ними знакомитесь. Рад, что у вас все работает! - person Hovercraft Full Of Eels; 16.07.2014