在JScrollingPanel

时间:2015-06-07 08:25:09

标签: java swing jpanel jscrollpane

我试图为我的平台游戏制作一个关卡编辑器,我希望我的等级为100 x 100平方。

编辑工作到目前为止,但我无法滚动浏览JPanel。我一直在玩,我已经做了一个小型的测试课程来摆弄我发布的内容。
如果你运行它,它只显示网格。但是,如果我换掉两个变量(我会在哪里评论),它可以显示一个图像并根据该图像的大小滚动。

我只想为JPanel 提供滚动功能,这样我就可以滚动浏览 100 x 100平方的

import java.awt.BorderLayout;

public class ScrollPaneJ extends JFrame {

    // setting the panels
    private JPanel contentPane;
    private JScrollPane scrollPane;

    // dimensions/ variables of the grid
    int size = 16;
    int startX = 112;
    int startY = 48;
    int width = 30;
    int height = 30;

    // this is the grid
    String[][] grid = new String[width][height];

    // this is from the full editor class
    String currentImage = new String("platform");

    ImageIcon currentBackIcon = new ImageIcon("Resources/backdirttile.jpg");

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    // adding the scrollpane
                    ScrollPaneJ frame = new ScrollPaneJ();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ScrollPaneJ() {

        setTitle("Scrolling Pane Application");
        setSize(new Dimension(300, 200));
        setBackground(Color.gray);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // defining the top and bottom panels, bottom is what I think I'm
        // drawing on, top is where the scrollpanel goes, I copied this code
        // from the internet and I'm not too sure how it works
        JPanel topPanel = new JPanel();
        JPanel bottomPanel = new JPanel(new GridLayout());

        bottomPanel.setLayout(new BorderLayout());
        getContentPane().add(bottomPanel);

        topPanel.setLayout(new BorderLayout());
        getContentPane().add(topPanel);

        // this is the label I was talking about
        Icon image = new ImageIcon("src/MenuDesign.jpg");
        JLabel label = new JLabel(image);

        // Create a tabbed pane
        // if you set it to say label instead of bottomPanel, you can scroll
        // through the size of the label
        scrollPane = new JScrollPane(bottomPanel);
        scrollPane.setBounds(40, 40, 100, 100);
        // set it label here as well.
        scrollPane.getViewport().add(bottomPanel);

        // I was hoping this would force the scrollbar in but it does nothing
        scrollPane
                .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setBounds(50, 30, 300, 50);
        JPanel contentPane = new JPanel(null);
        contentPane.setPreferredSize(new Dimension(500, 400));
        contentPane.add(scrollPane);

        topPanel.add(scrollPane, BorderLayout.CENTER);
        init();
    }

    public void init() {
        // this sets the grid to empty
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                grid[x][y] = "";

            }

        }
    }

    @Override
    public void paint(Graphics g) {
        // this paints the grid
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.black);

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                g2d.drawRect(x * size + startX, y * size + startY, size, size);

                if (grid[x][y].equals("")) {

                    g2d.drawImage(currentBackIcon.getImage(),
                            x * size + startX, y * size + startY, null);

                }

                g2d.setColor(Color.black);
                g2d.drawRect((x * size) + 1 + startX, (y * size) + 1 + startY,
                        size, size);

            }
        }
    }

    public void drawTile() {
        // this isn't enabled which is why you can't paint the grid, however it
        // would change the tile of the square you're mouse is on, to the
        // current tile, it works and isn't really important for what i need
        // help with
        PointerInfo a = MouseInfo.getPointerInfo();
        Point b = a.getLocation();
        int mouseX = (int) b.getX();
        int mouseY = (int) b.getY();
        int gMX = ((mouseX - 48) / 16) - 4;
        int gMY = ((mouseY - 48) / 16) - 3;

        grid[gMX][gMY] = currentImage;
        repaint();
    }
}

2 个答案:

答案 0 :(得分:3)

  1. scrollPane.getViewport().add(bottomPanel);应该更像scrollPane.getViewportView(bottomPanel);
  2. 你不应该直接画到画框上,因为儿童组件可以在没有通知父母的情况下进行绘画,这意味着你画过的东西可能会被部分消灭掉。相反,这种绘画应该在一个自定义组件中完成,该组件充当JScrollPane的{​​{1}}视图。
  3. JViewport需要两件事,首先,组件想要的大小(JScrollPane)和视口视图的大小。如果组件未实现preferredSize接口,则组件的Scrollable也用于确定该接口。这就是preferredSize将起作用的原因。
  4. JLabelJScrollPane作为主要子组件。 JViewport应该只有一个组件,通常通过JViewportJScrollPane#setViewportView方法分配

    JScrollPane

    有关详细信息,请参阅How to Use Scroll Panes

    创建一个扩展JViewport#setView的自定义组件并覆盖它的JPanel方法,以返回所需组件的大小。覆盖它的getPreferredSize方法并执行自定义绘制。

    在其他组件上叠加自定义绘画更加困难

答案 1 :(得分:0)

您也可以在面板中添加JScrollPane,如下所示

public static Document getDoc(String html) {
        Tidy tidy = new Tidy();
        tidy.setInputEncoding("UTF-8");
        tidy.setOutputEncoding("UTF-8");
        tidy.setWraplen(Integer.MAX_VALUE);
        // tidy.setPrintBodyOnly(true);
        tidy.setXmlOut(false);
        tidy.setShowErrors(0);
        tidy.setShowWarnings(false);
        // tidy.setForceOutput(true);
        tidy.setQuiet(true);
        Writer out = new StringWriter();
        PrintWriter dummyOut = new PrintWriter(out);
        tidy.setErrout(dummyOut);
        tidy.setSmartIndent(true);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(html.getBytes());
        Document doc = tidy.parseDOM(inputStream, null);
        return doc;
    }