首先,我承认我在使用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编码很棘手!
答案 0 :(得分:2)
处理图片的最佳方式是使用JLabel
和createImageIcon。已有很多代码用于处理图像,所以不要重新发明轮子。
答案 1 :(得分:1)
这里有很多评论,但JPanel默认为小尺寸。部分内容由您使用的LayoutManager决定。在这种情况下,通过不设置默认值或preferredSize,它自己选择10,10像素。您需要指定大小,它不会根据图像的尺寸自行计算出来。
您可能希望查看具有JXImagePanel的Java SwingX项目,该项目与ImgPanel基本相同。
我知道这只能解决问题的一部分,但就像trashgod评论一样,将其简化为较小的代码问题将有助于单独解决每个问题