【问题标题】:Put component inside the smaller one将组件放入较小的组件内
【发布时间】:2017-11-04 22:00:18
【问题描述】:

我想像这样得到带有 DrawCanvas(960x960) 的 Frame(640x640):

所以 DrawCanvas 的部分必须是隐藏的并且框架居中。我应该选择什么布局?现在我将 DrawCanvas 放在框架内,如下所示:

    class extends JFrame {
        canvas = new DrawCanvas();
        canvas.setPreferredSize(new Dimension(960, 960));
        Container cp = getContentPane();
        cp.add(canvas);
        setPreferredSize(new Dimension(640, 640));
    }

【问题讨论】:

  • 我认为您可以使用Boxlayout 来做到这一点,用网格区域填充空格。

标签: java swing layout jframe


【解决方案1】:

再次如上一个问题所述,一种方法是将内部组件嵌入 JScrollPane 中,但去掉滚动条的滚动窗格。

例如,假设您有一个名为 DrawPanel 的类,它扩展了 JPanel 并拥有 12 x 12 的单元格网格,但您只想显示 8 x 8 个单元格。你可以让这个类实现 Scrollable 接口,让它的getPreferredScrollableViewportSize 方法返回你想要显示的尺寸,而它的getPreferredSize 方法将返回组件的实际尺寸:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Scrollable;

@SuppressWarnings("serial")
public class DrawPanel extends JPanel implements Scrollable {
    public static final int VISIBLE_ROW_COUNT = 8;
    private static final int ROW_COUNT = 12;
    private static final Color DARK_COLOR = Color.DARK_GRAY;
    private static final Color LIGHT_COLOR = Color.WHITE;
    private int cellWidth;

    public DrawPanel(int cellWidth) {
        super(new GridLayout(ROW_COUNT, ROW_COUNT));
        this.cellWidth = cellWidth;
        Dimension prefSize = new Dimension(cellWidth, cellWidth);
        for (int i = 0; i < ROW_COUNT; i++) {
            for (int j = 0; j < ROW_COUNT; j++) {
                JPanel cell = new JPanel();
                cell.setPreferredSize(prefSize);
                Color c = i % 2 == j % 2 ? DARK_COLOR : LIGHT_COLOR;
                cell.setBackground(c);
                add(cell);

                // TODO: delete the code below. For demo/debug purposes only
                String text = String.format("[%d, %d]", j, i);
                JLabel label = new JLabel(text);
                c = c == DARK_COLOR ? LIGHT_COLOR : DARK_COLOR;
                label.setForeground(c);
                cell.add(label);
                // TODO: end delete block
            }
        }
    }

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        Dimension viewportSize = new Dimension(VISIBLE_ROW_COUNT * cellWidth, VISIBLE_ROW_COUNT * cellWidth);
        return viewportSize;
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation,
            int direction) {
        return cellWidth;
    }

    @Override
    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return false;
    }

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
            int direction) {
        return 1;
    }

    // note that getPreferredSize already returns the size of the 12 x 12 grid
    // since it is composed of a grid sized JPanels

}

然后你可以把它放在你的 JScrollPane 中,

private static final int CELL_WIDTH = 80;
private DrawPanel drawPanel = new DrawPanel(CELL_WIDTH);
private JScrollPane drawPanelScrollPane = new JScrollPane(drawPanel); 

摆脱滚动条,

    drawPanelScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    drawPanelScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);

并将其滚动到您想要左上角的位置:

    int x = 2 * CELL_WIDTH;
    int y = x;
    Point pt = new Point(x, y);
    drawPanelScrollPane.getViewport().setViewPosition(pt);

示例 GUI:

import java.awt.BorderLayout;
import java.awt.Point;

import javax.swing.*;

@SuppressWarnings("serial")
public class FrameAGrid extends JPanel {
    private static final int CELL_WIDTH = 80;
    private DrawPanel drawPanel = new DrawPanel(CELL_WIDTH);
    private JScrollPane drawPanelScrollPane = new JScrollPane(drawPanel); 

    public FrameAGrid() {
        drawPanelScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        drawPanelScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        setLayout(new BorderLayout());
        add(drawPanelScrollPane);

        int x = 2 * CELL_WIDTH;
        int y = x;
        Point pt = new Point(x, y);
        drawPanelScrollPane.getViewport().setViewPosition(pt);
    }


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

        JFrame frame = new JFrame("FrameAGrid");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

这显示为:

注意左上角是 2, 2 而不是 0, 0

【讨论】:

  • 非常感谢您的工作!我认为 JScrollPane,根据它的名字,需要滚动条,我不能删除它们。我会试试这个。
  • 您可以在不使用 JScrollPane 的情况下将任何组件嵌入到任何其他组件中,但这样做的好处是,如果您以后碰巧想要显示未显示的区域,您只需移动视口即可。跨度>
  • 为什么不在 0,0?
  • @diegofm:他试图在较小的组件中显示较大的组件,而边距不可见。这些数字仅用于演示目的。
  • @diegofm,这是我的特殊需求。
猜你喜欢
  • 2018-05-17
  • 2021-08-03
  • 1970-01-01
  • 2019-09-24
  • 2020-07-19
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多