qasinformatik
asked on
ui-functionality for chat textbox (JTextPane?) - problems with coordinates, background for enire lines...
Hello Experts!
I'm upgrading a java chat tool to a newer version and have a problem with my User Interface.
The messages shall appear in a multi-functional text-window (actual version is text with font-styles
in a JTextPane).
The requirements:
- every message is visually separated from the others and must be
- copy out of Text-window must be possible (Ctrl + c)
--> also Header information like "From Walter" and time should be extracted
- pop-up menu at rightclick --> delete/add user to personal contacts if not already in it
- buttons for delete/add user to personal contacts
- hyperlinks and mail-addresses shall be clickable
How it shall look like:
__________________________ __________ __________ _________
< From Walter 01.06.2006 - 17:01:54 [P] [X]
This is the message, that was sent from Walter to Me.
__________________________ __________ __________ _________
< To Walter 01.06.2006 - 17:01:54 [P] [X]
This is the response
-> [p] is the button for adding user to personal contacts
-> [x] for deleting the message
-> i will call the following 2 lines the header:
__________________________ __________ __________ _________
< From Walter 01.06.2006 - 17:01:54 [P] [X]
1) Which java component shall i use?
- JTextarea doesn't support Buttons and other included components - so not interesting
- JTextPane is nice but i missed much functionality (see next points)
- are there any more? i just tried JTextPane
2) The Buttons:
in a JTextPane i can add the buttons as components. But i cannot position them where i want to, they are simply
appended to the end of the text - thats ok but i would prefer to be able to position them if possible - is there
a way?
3) The Background for the Header-Line
I want that the entire header-line has a background color that goes from the right border to the
left border even when resizing the window --> i found out how to set background color to the font-Style
but only the text has a background -> i want the entire line to have a background
- it shall look like when u select a message from the inbox message list in Microsoft Outlook or when hovering
divs in dynamic html.
I tried that but it was impossible for me to find out the pixel coordinates from any text-line.
I tried to temporary set the caret into the line and get the x/y-coordinates by using the following
code (this code shall switch the background color per line from red to blue - for testing):
But somehow it didnt work - the variable "coordinates" was null most times.
public void paintComponent (Graphics g) {
// Get section element
Element section = getDocument().getDefaultRo otElement( );
// Get number of paragraphs.
// In a text pane, a span of characters terminated by single
// newline is typically called a paragraph.
int paraCount = section.getElementCount();
// save the caret position
int tempPos = getCaretPosition();
// Get index ranges for each paragraph
for (int i=0; i<paraCount; i++) {
Element e = section.getElement(i);
int rangeStart = e.getStartOffset();
this.setCaretPosition(rang eStart);
Point coordinates = getCaret().getMagicCaretPo sition();
if(coordinates!= null){
if(g.getColor()==Color.RED )
g.setColor(Color.BLUE);
else
g.setColor(Color.RED);
System.out.println(coordin ates.x + " - " + coordinates.y);
g.fillRect(0 , coordinates.y, getWidth(), coordinates.y + 20);
}
}
// set the caret position back
this.setCaretPosition(temp Pos);
}
The problem is that if i cannot find out which message-element is at a certain position, how shall i know
which message to delete if right-click was performed.
--> how can i find out the x,y-coordinates of a line and even better of any text-part or Button?
4) Selecting an entire message block on rightclick
--> is there a way to select an entire message block? (which is Header + the lines until the next header) for example on right click -
so that the user knows which message he's referencing for deletion.
I get the x/y positions of the click-event but how can i find out which message was clicked?
Thanks in advance.
I'm upgrading a java chat tool to a newer version and have a problem with my User Interface.
The messages shall appear in a multi-functional text-window (actual version is text with font-styles
in a JTextPane).
The requirements:
- every message is visually separated from the others and must be
- copy out of Text-window must be possible (Ctrl + c)
--> also Header information like "From Walter" and time should be extracted
- pop-up menu at rightclick --> delete/add user to personal contacts if not already in it
- buttons for delete/add user to personal contacts
- hyperlinks and mail-addresses shall be clickable
How it shall look like:
__________________________
< From Walter 01.06.2006 - 17:01:54 [P] [X]
This is the message, that was sent from Walter to Me.
__________________________
< To Walter 01.06.2006 - 17:01:54 [P] [X]
This is the response
-> [p] is the button for adding user to personal contacts
-> [x] for deleting the message
-> i will call the following 2 lines the header:
__________________________
< From Walter 01.06.2006 - 17:01:54 [P] [X]
1) Which java component shall i use?
- JTextarea doesn't support Buttons and other included components - so not interesting
- JTextPane is nice but i missed much functionality (see next points)
- are there any more? i just tried JTextPane
2) The Buttons:
in a JTextPane i can add the buttons as components. But i cannot position them where i want to, they are simply
appended to the end of the text - thats ok but i would prefer to be able to position them if possible - is there
a way?
3) The Background for the Header-Line
I want that the entire header-line has a background color that goes from the right border to the
left border even when resizing the window --> i found out how to set background color to the font-Style
but only the text has a background -> i want the entire line to have a background
- it shall look like when u select a message from the inbox message list in Microsoft Outlook or when hovering
divs in dynamic html.
I tried that but it was impossible for me to find out the pixel coordinates from any text-line.
I tried to temporary set the caret into the line and get the x/y-coordinates by using the following
code (this code shall switch the background color per line from red to blue - for testing):
But somehow it didnt work - the variable "coordinates" was null most times.
public void paintComponent (Graphics g) {
// Get section element
Element section = getDocument().getDefaultRo
// Get number of paragraphs.
// In a text pane, a span of characters terminated by single
// newline is typically called a paragraph.
int paraCount = section.getElementCount();
// save the caret position
int tempPos = getCaretPosition();
// Get index ranges for each paragraph
for (int i=0; i<paraCount; i++) {
Element e = section.getElement(i);
int rangeStart = e.getStartOffset();
this.setCaretPosition(rang
Point coordinates = getCaret().getMagicCaretPo
if(coordinates!= null){
if(g.getColor()==Color.RED
g.setColor(Color.BLUE);
else
g.setColor(Color.RED);
System.out.println(coordin
g.fillRect(0 , coordinates.y, getWidth(), coordinates.y + 20);
}
}
// set the caret position back
this.setCaretPosition(temp
}
The problem is that if i cannot find out which message-element is at a certain position, how shall i know
which message to delete if right-click was performed.
--> how can i find out the x,y-coordinates of a line and even better of any text-part or Button?
4) Selecting an entire message block on rightclick
--> is there a way to select an entire message block? (which is Header + the lines until the next header) for example on right click -
so that the user knows which message he's referencing for deletion.
I get the x/y positions of the click-event but how can i find out which message was clicked?
Thanks in advance.
Better use JEditorPane and set the text as HTML content with your formatting!
whats the benefit of JEditorPane to JTextPane since JTextPane is derived from JEditorPane and has all its parents functionality plus more
for the sake of html customization
ASKER
If i change to text/html - how can i append the text? The setText replaces the text. If I use HTML Code - can I still use my StyledDocument or do i have to change everything to html?
With the StyledDocuments i can insert a JButton. How is that handled with HTML Code? I guess i will have to use HTML Buttons --> but how can I handle the onClick Event?
With the StyledDocuments i can insert a JButton. How is that handled with HTML Code? I guess i will have to use HTML Buttons --> but how can I handle the onClick Event?
> how can i append the text?
insertText()
> can I still use my StyledDocument
yes
insertText()
> can I still use my StyledDocument
yes
need not be a html button but an image with hipherlink!
ASKER
--> the JTextPanel-Definitions
private javax.swing.JTextPane getMessagesJTP() {
if(messagesJTP == null) {
messagesJTP = new javax.swing.JTextPane();
messagesJTP.setEditable(fa
//messagesJTP.setContentTy
messagesDoc = (StyledDocument)messagesJT
// Create a style object and then set the style attributes
sendTextStyle = messagesDoc.addStyle("send
StyleConstants.setFontFami
StyleConstants.setFontSize
//StyleConstants.setBold(t
//StyleConstants.setBackgr
StyleConstants.setForegrou
receiveTextStyle = messagesDoc.addStyle("rece
StyleConstants.setFontFami
StyleConstants.setFontSize
//StyleConstants.setBold(t
//StyleConstants.setBackgr
StyleConstants.setForegrou
sendUserStyle = messagesDoc.addStyle("send
StyleConstants.setFontFami
StyleConstants.setBold(sen
StyleConstants.setFontSize
//StyleConstants.setBackgr
StyleConstants.setForegrou
receiveUserStyle = messagesDoc.addStyle("rece
StyleConstants.setFontFami
StyleConstants.setBold(rec
StyleConstants.setFontSize
//StyleConstants.setBackgr
StyleConstants.setForegrou
lineStyle = messagesDoc.addStyle("line
StyleConstants.setFontFami
StyleConstants.setBold(lin
StyleConstants.setFontSize
//StyleConstants.setBackgr
StyleConstants.setForegrou
errorStyle = messagesDoc.addStyle("erro
StyleConstants.setFontFami
StyleConstants.setBold(err
StyleConstants.setFontSize
//StyleConstants.setBackgr
StyleConstants.setForegrou
}
return messagesJTP;
}
--> This is where i append the message to the JTextPane
if(messageNo != 0){
try{
messagesDoc.insertString(m
}catch(Exception e){
}
}
// Append to document
try{
messagesDoc.insertString(m
messagesDoc.insertString(m
// delete Button
JButton deleteItemJB = new JButton(getIconClose());
deleteItemJB.setSize(12,12
deleteItemJB.setPreferredS
deleteItemJB.setLocation(7
deleteItemJB.addActionList
public void actionPerformed(ActionEven
MessageMask.this.setVisibl
}
});
// The component must first be wrapped in a style
JButton addToFavoritesJB = new JButton(getIconMinimize())
addToFavoritesJB.setSize(1
addToFavoritesJB.setPrefer
addToFavoritesJB.setLocati
JPanel containerJP = new JPanel();
containerJP.setPreferredSi
containerJP.setLayout(null
containerJP.add(deleteItem
containerJP.add(addToFavor
// The component must first be wrapped in a style
Style style = messagesDoc.addStyle("butt
StyleConstants.setAlignmen
StyleConstants.setComponen
// Insert the component at the end of the text
messagesDoc.insertString(m
messagesDoc.insertString(m
}catch(Exception e){
}
--------------------------
Thats the code which I use to append the text to the JTextPane
Since I didn't get the code to work I tried to do it with the StyledDocument - but I dont get the background for the entire Line then.
@ hoomany
can u give me a codeexample
--> i tried to but finally the only way i saw was the setText()
--> i tried to combine StyledDocument and HTML - but it looked like i had to decide wheter i wanted to use HTML or StyledDocument with the possibility to insert other Components like JPanels, JButtons and whatever.
@ Ksivananth
What i dont understand is how can I catch the event out of the HTML-Document?
If i write the HTML-Code what do i have to put in the href so that a Java-function is called.
--> please give me a code example
And there is one more limitation with the HTML Code
("<p><div style=\"background-color: #FF0000\"><b><font face=\"Tahoma\" size=\"7\">Hello</font></b
the background isn't painted up to the border of the JTextPane - there are always about 1 or 2 pixel on each side which are not painted.
And 2 more questions:
5) is there a way to draw a break line?
i used: messagesDoc.insertString(m
--> if i resize the window the line won't to up to the borders
6) is there a way to use two alignments in the same line?
__________________________
< From Walter 01.06.2006 - 17:01:54 [P] [X]
Thats my header line --> i want the buttons [P] and [X] to be aligned on the right. The text before (but in the same line) shall be aligned on the left
lots off examples
http://www.java2s.com/ExampleCode/Swing-JFC/TextPane.htm
http://www.java2s.com/ExampleCode/Swing-JFC/TextPane.htm
> I tried to do it with the StyledDocument - but I dont get the background for the entire Line then
I was also unable to get it to work using StyledDocument, but still insertText(html content) should work
I was also unable to get it to work using StyledDocument, but still insertText(html content) should work
ASKER
ok i solved the point with the background-color by using HTML and StyleSheets
thats the new code:
private javax.swing.JTextPane getMessagesJTP() {
if(messagesJTP == null) {
messagesJTP = new javax.swing.JTextPane();
messagesJTP.setEditable(fa lse);
messagesJTP.setContentType ("text/htm l");
HTMLEditorKit kit = new HTMLEditorKit();
//HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument( );
StyleSheet sheet = kit.getStyleSheet();
sheet.addRule( "p {font-size: small}" );
sheet.addRule( "body {font-size: 12pt;color: #444444}" );
sheet.addRule( "div.sendMessage {font-size: 12pt;background-color: #b4b6d3;height:15;}" );
sheet.addRule( "div.receiveMessage {font-size: 12pt;background-color: #AAAAFF;height:15;}" );
}
return messagesJTP;
}
--> and thats the code for writing it out on TextPanel
Vector selMessages = MessageContainer.getAllMes sages();
String code = "<html>\n<title>iCom Message window</title>\n<body>";
// prepare messages for writing
for(int i=0; i<selMessages.size(); i++){
Message msg = (Message)(selMessages.get( i));
code += "<div width=\"100%\" class=\"receiveMessage\" >";
code += "> " + msg.getFrom()+ "\t" + msg.getReceiveDate().toStr ing() + " - " + msg.getReceiveTime().toStr ing();
code += "</div>\n";
code += msg.getMessage().replaceAl l("\n", "<br>\n");
code += "\n";
}
code += "</body></html>";
getMessagesJTP().setText(c ode);
--> So the points 1, 3, 5 and 6 are solved.
Rest:
7) Now I need the buttons to be placed + made clickable - I have pictures/icons for them but I dont have them on a webserver since the application shall be installed locally.
--> So what i want is a Button with a picture (safed in JAR-File) which I can click
Questions form my side:
- which URL do I use for them (pics are in a Jar-File) --> i get the other pictures/icons as followed:
-----------------
private ImageIcon getIconClose() throws Exception{
if(iconClose == null){
URL url = getClass().getResource("/q as/layout/ x.jpg");
iconClose = new ImageIcon(url);
}
return iconClose;
}
-----------------
--> with a JButton component it would be quite easy (if there was a way to allow JButtons in the HTML-Code that would solve this point)
- how do i define the onclick-event - how is the link between html-source code and Event handling realised?
4) Selecting an entire message block on rightclick
--> is there a way to select an entire message block? (which is Header + the message lines until the next header) for example on right click -
so that the user knows which message he's referencing for deletion.
--> can I make a javascript pass the messageNo to the Java-Application? Do i have to realise the event handling in javascript or in the Java-Application?
thats the new code:
private javax.swing.JTextPane getMessagesJTP() {
if(messagesJTP == null) {
messagesJTP = new javax.swing.JTextPane();
messagesJTP.setEditable(fa
messagesJTP.setContentType
HTMLEditorKit kit = new HTMLEditorKit();
//HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(
StyleSheet sheet = kit.getStyleSheet();
sheet.addRule( "p {font-size: small}" );
sheet.addRule( "body {font-size: 12pt;color: #444444}" );
sheet.addRule( "div.sendMessage {font-size: 12pt;background-color: #b4b6d3;height:15;}" );
sheet.addRule( "div.receiveMessage {font-size: 12pt;background-color: #AAAAFF;height:15;}" );
}
return messagesJTP;
}
--> and thats the code for writing it out on TextPanel
Vector selMessages = MessageContainer.getAllMes
String code = "<html>\n<title>iCom Message window</title>\n<body>";
// prepare messages for writing
for(int i=0; i<selMessages.size(); i++){
Message msg = (Message)(selMessages.get(
code += "<div width=\"100%\" class=\"receiveMessage\" >";
code += "> " + msg.getFrom()+ "\t" + msg.getReceiveDate().toStr
code += "</div>\n";
code += msg.getMessage().replaceAl
code += "\n";
}
code += "</body></html>";
getMessagesJTP().setText(c
--> So the points 1, 3, 5 and 6 are solved.
Rest:
7) Now I need the buttons to be placed + made clickable - I have pictures/icons for them but I dont have them on a webserver since the application shall be installed locally.
--> So what i want is a Button with a picture (safed in JAR-File) which I can click
Questions form my side:
- which URL do I use for them (pics are in a Jar-File) --> i get the other pictures/icons as followed:
-----------------
private ImageIcon getIconClose() throws Exception{
if(iconClose == null){
URL url = getClass().getResource("/q
iconClose = new ImageIcon(url);
}
return iconClose;
}
-----------------
--> with a JButton component it would be quite easy (if there was a way to allow JButtons in the HTML-Code that would solve this point)
- how do i define the onclick-event - how is the link between html-source code and Event handling realised?
4) Selecting an entire message block on rightclick
--> is there a way to select an entire message block? (which is Header + the message lines until the next header) for example on right click -
so that the user knows which message he's referencing for deletion.
--> can I make a javascript pass the messageNo to the Java-Application? Do i have to realise the event handling in javascript or in the Java-Application?
pane.addHyperlinkListener( new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkE vent event) {
...
}
});
public void hyperlinkUpdate(HyperlinkE
...
}
});
hope hoomany's post helps regarding the hyperlink event!
ASKER
Well,
I solved question 7 by myself.
I found a complete example for the .addHyperlinkListener somewhere else.
I would have wished some code examples - it was quite hard to find something that handled my problem.
The only thing that is still open is point 4 - selecting an entire message block on rightclick.
Would be nice if someone had a way to do that.
I have a html-block encapsulated in a div --> i want to handle the onclick event in Java - not in Javascript. If there is a way to pass the event to javascript thats ok too.
The entire HTML-Text of the page is in a JTextPane
-->
Vector selMessages = MessageContainer.getAllMes sages();
String code = "<html>\n<title>iCom Message window</title>\n<body>";
// prepare messages for writing
for(int i=0; i<selMessages.size(); i++){
Message msg = (Message)(selMessages.get( i));
code += "<div id=\"+msg.getMessageNo()+\ " width=\"100%\" class=\"receiveMessage\" >";
code += "> " + msg.getFrom()+ "\t" + msg.getReceiveDate().toStr ing() + " - " + msg.getReceiveTime().toStr ing();
code += "</div>\n";
code += msg.getMessage().replaceAl l("\n", "<br>\n");
code += "\n";
}
code += "</body></html>";
--> if I added an onClick='callParentProgram ();' to the div in the line (code += "<div width=\"100%\" class=\"receiveMessage\" >";) - would there be a way to get the event up to java?
--> Or can I add an ActionListener to the JTextPane which catches the rightClick-Event? But how would I be able to find out, which div was clicked?
I solved question 7 by myself.
I found a complete example for the .addHyperlinkListener somewhere else.
I would have wished some code examples - it was quite hard to find something that handled my problem.
The only thing that is still open is point 4 - selecting an entire message block on rightclick.
Would be nice if someone had a way to do that.
I have a html-block encapsulated in a div --> i want to handle the onclick event in Java - not in Javascript. If there is a way to pass the event to javascript thats ok too.
The entire HTML-Text of the page is in a JTextPane
-->
Vector selMessages = MessageContainer.getAllMes
String code = "<html>\n<title>iCom Message window</title>\n<body>";
// prepare messages for writing
for(int i=0; i<selMessages.size(); i++){
Message msg = (Message)(selMessages.get(
code += "<div id=\"+msg.getMessageNo()+\
code += "> " + msg.getFrom()+ "\t" + msg.getReceiveDate().toStr
code += "</div>\n";
code += msg.getMessage().replaceAl
code += "\n";
}
code += "</body></html>";
--> if I added an onClick='callParentProgram
--> Or can I add an ActionListener to the JTextPane which catches the rightClick-Event? But how would I be able to find out, which div was clicked?
ASKER
small correction: *If there is a way to pass the event from javascript to java thats ok too.
--> is there no way to edit a message?
--> is there no way to edit a message?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
somthing like this ? I guess
JTextPane tp = new JTextPane();
tp.setContentType("text/ht
tp.setText("<p><div style=\"background-color: #FF0000\"><b><font face=\"Tahoma\" size=\"7\">Hello</font></b