Resizing JTextPane in JPanel

I am trying to create an IM program as a kind of hobby project. I have been experimenting with UI designs and trying to get this prototype to make the actual display of messages work.

The frame is currently set up like this:

  • A JPanel is installed in the JFrame content area, which uses a BoxLayout using Y_AXIS.
  • The content pane contains the TextMessage objects that I would like to display, individually added to the content pane.

The TextMessage is configured like this:

  • The message and sender string is stored inside a TextMessage object that extends the JTextPane and uses StyledDocument for formatting.
  • The TextMessage is placed inside the JPanel to ensure that the object is correctly positioned in the BoxLayout. The JPanel is set to FlowLayout, which binds the TextMessage object to any edge of the JPanel, depending on the boolean.

So far, everything works as we would like, with one notable exception. When I resize the JFrame, the TextMessage objects do not change and instead just disappear from the edge of the screen.

Expected Result:

http://oi57.tinypic.com/nnl3bn.jpg

Actual result:

http://oi62.tinypic.com/2re7dbc.jpg

JFrame class:

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 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 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 object (JPanel container for TextMessageContent):

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;
    }
}

      

TextMessageContent class: (JTextPane)

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());
    }
}

      

I've read about simply adding JTextPane directly to containers and whatnot, but with this setup JPanel wrapping text message content, it is necessary that the content area BoxLayout does not make the text messages fill the entire panel.

Any suggestions?

+3


source to share


1 answer


I read about just adding JTextPane directly to containers and whatnot, but with this setup the JPanel wrapping the text message content needs the BoxLayout of the content area not to make the text messages fill the whole panel



Not sure if this helps or not, but BoxLayout respects the maximum size of the components added to it. Perhaps you can override the method getMaximumSize()

to control the width. Width must be less than the preferred width or width of the parent container.

0


source







All Articles