尽管流程布局,图像堆叠在彼此的顶部?

时间:2011-06-09 19:52:40

标签: java image swing user-interface jpanel

首先,我承认我在使用Swing编写GUI时非常陌生,所以请记住这一点。

我制作了一个GUI,顶部有一个JPanel,用于显示图像,另一个底部包含几个构成聊天的GUI组件。我所有的聊天都得到了照顾(尽管欢迎您指出错误和改进)。我现在关心的是处理上部JPanel中的图像。

我的理解是,在处理图像时,将JPanel扩展到将图像绘制到GUI的新类是明智的。我根据我在本网站上找到的其他答案撰写了这样一堂课:

class ImgPanel extends JPanel
{

    private URL rUrl;
    private BufferedImage img;



    public ImgPanel(String filename) {
        super();
        try {
            rUrl = getClass().getResource(filename);
            if (rUrl != null) {
                img = ImageIO.read(rUrl);
            }
        } catch (IOException ex) {
            System.out.println("Couldn't find image file: " + filename);
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        this.setSize(240, 320); //If I do not set the size of the ImgPanel manually
                                //it for some reason gets the dimension (10, 10) and
                                //all the images are shrunk to fit it. Without this 
                                //line though, the images do not stack and are
                                //displayed as would be expected from flowLayout.
        g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
    }

}

从上面可以看出,我评论了我怀疑是问题的部分。我的GUI类看起来像这样:

public class ClientGUI extends JFrame{

    private JTextArea chatwindow;
    private JList users;
    private JTextField enterChat;
    private JPanel draftMonitor;
    private JPanel chatMonitor;
    private JPanel chatLeft;
    private DefaultListModel listModel;

    public ClientGUI(){
        super("Client");
        setLayout(new BorderLayout());

        chatwindow = new JTextArea();
        chatwindow.setEditable(false);
        chatwindow.setRows(15);
        chatwindow.setWrapStyleWord(true);
        DefaultCaret caret = (DefaultCaret)chatwindow.getCaret();
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

        listModel = new DefaultListModel();
        users = new JList(listModel);
        users.setVisibleRowCount(15);
        users.setPrototypeCellValue("AAAAAAAAAAAAAAAAAAAA"); 
                    //The above line is what I used to set the width of the JList,
                    //it has nothing to do with the question at hand, but I know 
                    //there must be plenty of ways to improve this rather crude 
                    //piece of coding.

        enterChat = new JTextField();

        chatLeft = new JPanel();
        chatLeft.setLayout(new BorderLayout());
        chatLeft.add(enterChat,"South");
        chatLeft.add(new JScrollPane(chatwindow),"Center");

        chatMonitor = new JPanel();
        chatMonitor.setLayout(new BorderLayout());
        chatMonitor.add(new JScrollPane(users),"East");
        chatMonitor.add(chatLeft,"Center");

        draftMonitor = new JPanel();
        draftMonitor.setLayout(new FlowLayout());
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));
        draftMonitor.add(new ImgPanel("exampleimage.jpg"));


        getContentPane().add(chatMonitor,"South");
        getContentPane().add(draftMonitor,"Center");

    }
    public JTextArea getChatWindow(){
        return chatwindow;
    }
    public JTextField getEnterChat(){
        return enterChat;
    }
    public JList getUsers(){
        return users;
    }
    public DefaultListModel getListModel(){
        return listModel;
    }

}

这样可以生成九个示例图像的副本,每个副本比右边的多一个(十个像素?),但堆叠在彼此的顶部,最左边的一个在顶部。他们没有居中,他们略微向右(显然是这样)。

如果没有ImgPanel类中的可疑行,它会产生我所期望的,在间隔开的行中居中的九个图像。但是它们远小于源图像的实际大小。

我很感谢能得到的所有帮助,这个GUI编码很棘手!

2 个答案:

答案 0 :(得分:2)

处理图片的最佳方式是使用JLabelcreateImageIcon。已有很多代码用于处理图像,所以不要重新发明轮子。

答案 1 :(得分:1)

这里有很多评论,但JPanel默认为小尺寸。部分内容由您使用的LayoutManager决定。在这种情况下,通过不设置默认值或preferredSize,它自己选择10,10像素。您需要指定大小,它不会根据图像的尺寸自行计算出来。

您可能希望查看具有JXImagePanel的Java SwingX项目,该项目与ImgPanel基本相同。

我知道这只能解决问题的一部分,但就像trashgod评论一样,将其简化为较小的代码问题将有助于单独解决每个问题