Java JTextPane在JPanel中调整大小
我正试图创建一个IM程序作为一种爱好项目。我一直在尝试UI设计,并一直在尝试让这个原型用于实际的消息显示 目前,框架是这样设置的Java JTextPane在JPanel中调整大小,java,swing,resize,jpanel,jtextpane,Java,Swing,Resize,Jpanel,Jtextpane,我正试图创建一个IM程序作为一种爱好项目。我一直在尝试UI设计,并一直在尝试让这个原型用于实际的消息显示 目前,框架是这样设置的 JFrame内容窗格设置为JPanel,它使用Y_轴的BoxLayout 内容面板包含我想显示的TextMessage对象,它们分别添加到内容窗格中 TextMessage对象是这样设置的 消息和发送者字符串存储在扩展JTextPane并使用StyledDocument进行格式化的TextMessage对象中 TextMessage被放置在JPanel中,以便在
- JFrame内容窗格设置为JPanel,它使用Y_轴的BoxLayout
- 内容面板包含我想显示的TextMessage对象,它们分别添加到内容窗格中
- 消息和发送者字符串存储在扩展JTextPane并使用StyledDocument进行格式化的TextMessage对象中
- TextMessage被放置在JPanel中,以便在BoxLayout中正确放置对象。JPanel被设置为FlowLayout,它根据布尔值将TextMessage对象固定在JPanel的任一边缘上
public class NewMain extends JFrame {
public NewMain() {
setTitle("SparrowIM Chat Bubble");
setPreferredSize(new Dimension(880, 550));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(true);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
setContentPane(panel);
add(new TextMessage("Hey, man. What's up?", "Jnk1296", true));
add(new TextMessage("Eh, nothing much.", "KeepJ96", false));
add(new TextMessage("Wbu? Anything new going on with you?", "KeepJ96", false));
add(new TextMessage("Nah, not really. Got a job interview coming up in a few " +
"days, though. Sorta excited for that, but sorta not. " +
"Other than that, life as usual. xD", "Jnk1296", true));
add(new TextMessage("lol Sounds good.", "KeepJ96", false));
add(new TextMessage("Yeah. How's the wife and kids, though?", "Jnk1296", true));
add(new TextMessage("Sarah still griping at you to get the roof patched up?", "Jnk1296", true));
add(new TextMessage("lol you could say that...", "KeepJ96", false));
pack();
setVisible(true);
}
public static void main(String[] args) {
new NewMain();
}
}
TextMessage对象(TextMessageContent的JPanel容器):
TextMessageContent类:(JTextPane)
我已经读过简单地将JTextPane直接添加到容器中之类的内容,但是通过这种设置,围绕文本消息内容的JPanel是必要的,以防止内容窗格的BoxLayout使文本消息填满整个面板
有什么建议吗
我已经读过简单地将JTextPane直接添加到容器和诸如此类的内容,但是通过这种设置,围绕文本消息内容的JPanel是必要的,以防止内容窗格的BoxLayout使文本消息填满整个面板
不确定它是否有用,但BoxLayout尊重添加到其中的组件的最大尺寸。也许您可以重写
getMaximumSize()
方法来控制宽度。宽度应为首选宽度或父容器宽度中的较小值。首先,我建议您考虑将JList与自定义项目渲染器一起使用,而不是使用这种复杂的设计。第二,您的try{}catch(异常e){是一个基本的非常糟糕的否。请更具体地说明您捕获的异常,如果发生异常,请至少打印stacktrace。另请参见和。这是由于在TextMessage类中使用FlowLayout造成的。FlowLayout不会试图限制其子项装入容器中。您可以使用BorderLayout取而代之的是yout或GridBagLayout。然后,您会发现JTextPane对于长内容的首选大小并不令人满意,因为它实际上是设计为进入JScrollPane内部的,这将迫使JTextPane的宽度与视口的宽度相匹配。@ControlAltDel JList的问题是每个单元格的大小都必须相同(我认为)。在像这样的聊天应用程序中,消息可能有不同的高度。请尝试将JTextPanes放置在JScrollPanes中,而不是直接添加。这是可能的,但我一直在尝试避免调用set*Size()如果可能的话。我之前尝试过类似的设置,结果非常不可靠。我一直在尽量避免调用set*Size()。
-我不建议调用set???Size()。您不应该这样做。如果您想要自定义行为,那么您将重写get???Size()方法。布局管理员只有在拥有足够信息以做出明智决策时才能执行其工作。
public class TextMessage extends JPanel {
private TextMessageContent content;
public TextMessage(String sender, String message, boolean localMessage) {
setBorder(new EmptyBorder(5, 5, 5, 5));
if (localMessage) {
setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
} else {
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
}
this.content = new TextMessageContent(sender, message, localMessage);
add(content);
}
public TextMessageContent getContent() {
return this.content;
}
}
public class TextMessageContent extends JTextPane {
private static final long serialVersionUID = -8296129524381168509L;
private String sender;
private String message;
private boolean isClient;
private Image background;
public TextMessageContent(String message, String sender, boolean isClient) {
// Define Data Points
this.message = message;
this.sender = sender;
this.isClient = isClient;
this.setEditable(false);
this.setOpaque(false);
this.setBorder(new EmptyBorder(7, 7, 7, 7));
// Fetch Background Image (Hard Location Temporary)
try {
if (this.isClient) {
background = ImageIO.read(
new File("/home/jacob/Desktop/orange.png"));
} else {
background = ImageIO.read(
new File("/home/jacob/Desktop/Green.png"));
}
} catch (Exception e) { return; }
// Create Text Styles
StyledDocument doc = getStyledDocument();
// Create Default Base Style
Style def = StyleContext.getDefaultStyleContext()
.getStyle(StyleContext.DEFAULT_STYLE);
Style regular = doc.addStyle("regular", def);
// Create Body Style
Style body = doc.addStyle("message", regular);
StyleConstants.setFontFamily(body, "Verdana");
StyleConstants.setFontSize(body, 12);
// Create Sender Style
Style foot = doc.addStyle("sender", body);
StyleConstants.setFontSize(foot, 9);
// Build Document
try {
doc.insertString(0, this.message + "\n", body);
doc.insertString(doc.getLength(), this.sender + " - " +
getSystemTime(), foot);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
@Override
public void paintComponent(Graphics g) {
background = ImageUtil.stretch(background, new Insets(5, 5, 5, 5),
new Dimension(getWidth(), getHeight()),
BufferedImage.TYPE_INT_ARGB);
g.drawImage(background, 0, 0, null);
super.paintComponent(g);
}
private String getSystemTime() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("h:mm a");
return sdf.format(cal.getTime());
}
}