【问题标题】:Scrollpanes wont appear until I click on them and there is no bar present to use滚动窗格在我单击它们之前不会出现,并且没有可用的栏
【发布时间】:2017-10-11 17:33:24
【问题描述】:

不确定我是否将其添加到错误的图层。可能不止一些错误。我将它添加到小程序中,因为我将删除 JFrame。 JFrame 仅用于测试目的。我不知道我是否设置了滚动窗格错误或什么。最终目标是通过按钮将图片添加到jpanel,并且如果它大于面板,则能够滚动。

public class main {

    public static JFrame f = new JFrame();
    public static JApplet a = new JApplet();
    public static JPanel p = new JPanel();
    public static JButton b = new JButton();
    public static JScrollPane pane = new JScrollPane(p, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    public static JLabel gameimage; 
    public static void main(String[] args) {

        f.setSize(1000,800);

        a.setBounds(0,0,1000,800);
        a.setVisible(true);
        a.setBackground(Color.WHITE);

        p.setBounds(0, 0, 1000, 800);
        p.setVisible(true);
        p.setBackground(Color.WHITE);
        p.setLayout(null);
        p.setOpaque(true);

        pane.getVerticalScrollBar();
        pane.getHorizontalScrollBar();
        pane.setVisible(true);

        b.setBounds(955, 0, 40, 30);
        b.setText("+");
        b.setFont(new Font("Times Roman", Font.BOLD, 30));
        b.setVisible(true);
         b.setBorder(javax.swing.BorderFactory.createLineBorder(Color.WHITE));

        b.setBackground(Color.WHITE);
        b.setForeground(Color.GREEN);

        b.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e) {
                    JFileChooser file = new JFileChooser();

                    file.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                    file.setAcceptAllFileFilterUsed(true);

                    if(file.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                        int width;
                        int height;
                        File f = file.getSelectedFile();
                        try {
                        BufferedImage bimg = ImageIO.read(new File(f.getAbsolutePath()));
                        width = bimg.getWidth();
                        height = bimg.getHeight();
                        String fname = f.getAbsolutePath();
                        gameimage = new JLabel("", new ImageIcon(fname), JLabel.CENTER);
                        gameimage.setSize(width,height);
                        gameimage.setOpaque(true);

                        a.revalidate();
                        a.repaint();
                        p.removeAll();
                        p.revalidate();
                        p.repaint();
                        pane.revalidate();
                        pane.repaint();
                        p.setSize(width,height);
                        p.add(gameimage);
                        p.add(b);
                        //p.add(pane);
                        a.getContentPane().add(pane);
                        }catch(IOException ioe) {

                        }


                    }else {
                        System.out.println("not working");
                    }
                }
        });

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setResizable(false);
        f.add(a);
        a.add(p);
        p.add(b);
    }
}

【问题讨论】:

  • 请创建一个minimal reproducible example。目前有很多东西可能不会导致问题。程序越小,人们就越有可能尝试使用它来解决问题。另一个建议:通过tour 稍微了解一下该网站。欢迎来到 SO
  • 不要使用null 布局。
  • 最后调用f.setVisible(true); - 另外,仅在更改后对您实际更改的容器调用revalidate/repaint
  • “我将它添加到小程序中是因为我将删除 JFrame” - 这似乎毫无意义,因为小程序不再受支持并且已被弃用
  • JScrollPanes 在视口组件上中继,通过preferred/minimum/maximum 属性提供大小提示,通常由LayoutManagers 提供,通过使用您已有效删除的null 布局支持

标签: java swing


【解决方案1】:

我不打算详细介绍,而是对代码进行注释

重点是:

  • 避免使用 null 布局,它们永远不会起作用,并且 Swing API 旨在操作布局管理器 API
  • Applet 已被弃用,您将无法从中获得任何您无法从 JFrame 或其他基于窗口的组件中获得的功能

虽然我没有采取直接任务,static 也是一个坏主意(在你使用它的情况下),如果可以的话尽量避免它

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Main {

    public static JFrame f = new JFrame();
    // Pointless, applets are deprecated
    // Besides, this isn't how you use them
    //public static JApplet a = new JApplet();
    public static JPanel p = new JPanel();
    public static JButton b = new JButton();
    public static JScrollPane pane = new JScrollPane(p, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    public static JLabel gameimage;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                f.setSize(1000, 800);

                //a.setBounds(0, 0, 1000, 800);
                //a.setVisible(true);
                //a.setBackground(Color.WHITE);
                // Pointless, the layout manager of the JScrollPane
                // will make these choices
                //p.setBounds(0, 0, 1000, 800);
                p.setVisible(true);
                p.setBackground(Color.WHITE);
                // !! This is root of your problem !!
                //p.setLayout(null);
                p.setLayout(new BorderLayout());
                // Pointless, it already is
                //p.setOpaque(true);

                // Pointless, you don't do anything with the returned value
                //pane.getVerticalScrollBar();
                //pane.getHorizontalScrollBar();
                // Pointless, it already is
                //pane.setVisible(true);
                // Pointless
                //b.setBounds(955, 0, 40, 30);
                b.setText("+");
                b.setFont(new Font("Times Roman", Font.BOLD, 30));
                // Pointless
                //b.setVisible(true);
                b.setBorder(javax.swing.BorderFactory.createLineBorder(Color.WHITE));
                b.setBackground(Color.WHITE);
                b.setForeground(Color.GREEN);

                b.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        JFileChooser file = new JFileChooser();

                        file.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                        file.setAcceptAllFileFilterUsed(true);

                        if (file.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                            int width;
                            int height;
                            File f = file.getSelectedFile();
                            try {
                                BufferedImage bimg = ImageIO.read(new File(f.getAbsolutePath()));
                                width = bimg.getWidth();
                                height = bimg.getHeight();
                                String fname = f.getAbsolutePath();
                                if (gameimage != null) {
                                    p.remove(gameimage);
                                }
                                gameimage = new JLabel("", new ImageIcon(fname), JLabel.CENTER);
                                gameimage.setSize(width, height);
                                gameimage.setOpaque(true);

                                //a.revalidate();
                                //a.repaint();
                                //p.removeAll();
                                // Not really what you want to do right now
                                // Besides, if you use a null layout, it won't do anything
                                //p.revalidate();
                                //p.repaint();
                                //pane.revalidate();
                                //pane.repaint();
                                //p.setSize(width, height);
                                p.add(gameimage);
                                //p.add(b);
                                //p.add(pane);
                                // Presumaly, pane should alredy be added to a container
                                //a.getContentPane().add(pane);
                                p.revalidate();
                                p.repaint();
                            } catch (IOException ioe) {

                            }

                        } else {
                            System.out.println("not working");
                        }
                    }
                });

                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                // Not what you want to call here
                //f.setVisible(true);
                // Probably not the best idea right now
                f.setResizable(false);
                //f.add(a);
                //a.add(p);
                // Good idea to add the scollpane to the container
                f.add(pane);
                p.add(b, BorderLayout.SOUTH);
                f.setVisible(true);
            }
        });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多