I have one JTextPane (1) and another one by it’s side (2). I’ve synched them and if a line is entered in (2), a line get’s entered in (1), but when I insert an image(24px), (2) resizes the line length automatically but (1) doesn’t resize of course.
How can I make a method that “when (2) is resized, resize (1)”?
I’ve tried when image is inserted in (2), to insert a black image(1px, 24px) in (1), but the problem with this is that if there are many images inserted in (2), they go to a new line, where (1) just adds them on one line and (1) gets a horizontal scrollbar. Sorry but I coundn’t make it shorter…
public class SSCCE extends JFrame {
private JPanel contentPane;
int wrapme=0;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SSCCE frame = new SSCCE();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SSCCE() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 338);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JScrollPane scrollName = new JScrollPane();
scrollName.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
scrollName.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollName.setBounds(10, 11, 99, 207);
contentPane.add(scrollName);
final JTextPane name = new JTextPane();
name.setEditable(false);
scrollName.setViewportView(name);
JScrollPane scrollChat = new JScrollPane();
scrollChat.setBounds(114, 11, 310, 207);
contentPane.add(scrollChat);
final JTextPane chat = new JTextPane();
chat.setText("Enter something!");
chat.setEditable(false);
scrollChat.setViewportView(chat);
scrollChat.getVerticalScrollBar().setModel(scrollName.getVerticalScrollBar().getModel());
final JTextArea chatEnter = new JTextArea();
chatEnter.setBounds(10, 229, 414, 60);
contentPane.add(chatEnter);
final StyledDocument nameDoc = name.getStyledDocument();
final StyledDocument chatDoc = chat.getStyledDocument();
final SimpleAttributeSet right = new SimpleAttributeSet();
StyleConstants.setForeground(right, Color.GRAY);
StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
nameDoc.setParagraphAttributes(0, nameDoc.getLength(), right, false);
final String TEXT_SUBMIT = "text-submit";
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
InputMap input = chatEnter.getInputMap();
ActionMap actions = chatEnter.getActionMap();
input.put(enter, TEXT_SUBMIT);
actions.put(TEXT_SUBMIT, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
try {
String s = chatEnter.getText();
s=s.replaceAll(":\\)", ":\\) ");
s=s.replaceAll(" ", " ");
//new line in name
String text = chatDoc.getText(0, chatDoc.getLength());
int count = 1;
int i = text.indexOf("\n");
while(i>=0){
count++;
i=text.indexOf("\n", i + 2);
}
int totalCharacters = chat.getText().length();
int lineCount = (totalCharacters == 0) ? 1 : 0;
try {
int offset = totalCharacters; // arbitrary non-zero number
while (offset > 0) {
offset = Utilities.getRowStart(chat, offset) - 1;
lineCount++;
}
} catch (BadLocationException ex) {
ex.printStackTrace();
}
lineCount-=wrapme;
while(count!=lineCount) {
nameDoc.insertString(nameDoc.getLength(), "\n", right);
count++;
wrapme++;
}
//new line in name End
nameDoc.insertString(nameDoc.getLength(), "Martin\n", right);
chatDoc.insertString(chatDoc.getLength(), s + "\n", null);
chat.select(chatDoc.getLength(), chatDoc.getLength());
name.select(nameDoc.getLength(), nameDoc.getLength());
} catch (BadLocationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
((AbstractDocument) chat.getDocument()).addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(final DocumentEvent de) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
StyledDocument doc = (StyledDocument) de.getDocument();
int start = Utilities.getRowStart(chat, Math.max(0, de.getOffset() - 1));
int end = Utilities.getWordStart(chat, de.getOffset() + de.getLength());
String text = doc.getText(start, (end - start)+1);
int i = text.indexOf(":)");
while (i >= 0) {
final SimpleAttributeSet attrs = new SimpleAttributeSet(doc.getCharacterElement(start + i).getAttributes());
if (StyleConstants.getIcon(attrs) == null) {
StyleConstants.setIcon(attrs, new new ImageIcon(ChatFrame.class.getResource("/smile.png")));
doc.remove(start + i, 2);
doc.insertString(start + i, ":)", attrs);
StyleConstants.setIcon(attrs, new ImageIcon(ChatFrame.class.getResource("/spacer.png")));
nameDoc.insertString(nameDoc.getLength()-6," ", attrs); //6 is "Martin" length
}
i = text.indexOf(":)", i + 2);
}
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
});
}
@Override
public void removeUpdate(DocumentEvent e) {
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
}
}
smile.png http://postimage.org/image/vm7e4gvp1/
spacer.png http://postimage.org/image/k0q09iq6l/
May be it’s better to use one main
JTextPane(chat) and multiple separateJTextPanes( or even labels) for each message sent. Then you can control the single message labels (or text panes) setting them desired height.The height could be calculated passing message start and end offsets to
modelToView()methods and calculating the difference.