[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

ui-functionality for chat textbox (JTextPane?) - problems with coordinates, background for enire lines...

Posted on 2006-06-08
17
Medium Priority
?
636 Views
Last Modified: 2008-01-09
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().getDefaultRootElement();

      // 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(rangeStart);
            Point coordinates = getCaret().getMagicCaretPosition();
                                    
            if(coordinates!= null){
                                          
                  if(g.getColor()==Color.RED)
                        g.setColor(Color.BLUE);
                  else
                        g.setColor(Color.RED);
                  System.out.println(coordinates.x + " - " + coordinates.y);
                                          
                  g.fillRect(0 , coordinates.y, getWidth(), coordinates.y + 20);
            }
                                    
      }
      // set the caret position back
      this.setCaretPosition(tempPos);
}

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.
0
Comment
Question by:qasinformatik
  • 6
  • 5
  • 4
  • +1
16 Comments
 
LVL 14

Expert Comment

by:hoomanv
ID: 16862865
3) The Background for the Header-Line
somthing like this ? I guess

  JTextPane tp = new JTextPane();
  tp.setContentType("text/html");
  tp.setText("<p><div style=\"background-color: #FF0000\"><b><font face=\"Tahoma\" size=\"7\">Hello</font></b></div></p>");
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16865821
Better use JEditorPane and set the text as HTML content with your formatting!
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16865862
whats the benefit of JEditorPane to JTextPane since JTextPane is derived from JEditorPane and has all its parents functionality plus more
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 26

Expert Comment

by:ksivananth
ID: 16865904
for the sake of html customization
0
 

Author Comment

by:qasinformatik
ID: 16867903
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?
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16867910
> how can i append the text?
insertText()

> can I still use my StyledDocument
yes
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16868089
need not be a html button but an image with hipherlink!
0
 

Author Comment

by:qasinformatik
ID: 16868279

--> the JTextPanel-Definitions
      private javax.swing.JTextPane getMessagesJTP() {
            if(messagesJTP == null) {
                  messagesJTP = new javax.swing.JTextPane();
                  messagesJTP.setEditable(false);
                  //messagesJTP.setContentType("text/html");
                  messagesDoc = (StyledDocument)messagesJTP.getDocument();
                      
                  // Create a style object and then set the style attributes
                  sendTextStyle = messagesDoc.addStyle("sendTextStyle", null);
              
                  StyleConstants.setFontFamily(sendTextStyle, "Verdana");
                  StyleConstants.setFontSize(sendTextStyle, 10);
                  //StyleConstants.setBold(textStyle, true);
                  //StyleConstants.setBackground(textStyle, Color.blue);
                  StyleConstants.setForeground(sendTextStyle, new Color(100,108,123));
                  
                  receiveTextStyle = messagesDoc.addStyle("receiveTextStyle", null);
              
                  StyleConstants.setFontFamily(receiveTextStyle, "Verdana");
                  StyleConstants.setFontSize(receiveTextStyle, 10);
                  //StyleConstants.setBold(textStyle, true);
                  //StyleConstants.setBackground(textStyle, Color.blue);
                  StyleConstants.setForeground(receiveTextStyle, new Color(0,0,0));


                
                  sendUserStyle = messagesDoc.addStyle("sendUserStyle", null);
                  StyleConstants.setFontFamily(sendUserStyle, "Verdana");
                  StyleConstants.setBold(sendUserStyle, true);
                  StyleConstants.setFontSize(sendUserStyle, 10);
                  //StyleConstants.setBackground(userStyle, Color.blue);
                  StyleConstants.setForeground(sendUserStyle, new Color(100,108,123));          
                  
                  
                  receiveUserStyle = messagesDoc.addStyle("receiveUserStyle", null);
                  StyleConstants.setFontFamily(receiveUserStyle, "Verdana");
                  StyleConstants.setBold(receiveUserStyle, true);
                  StyleConstants.setFontSize(receiveUserStyle, 10);
                  //StyleConstants.setBackground(userStyle, Color.blue);
                  StyleConstants.setForeground(receiveUserStyle, new Color(0,0,0));        
   
                  lineStyle = messagesDoc.addStyle("lineStyle", null);
                  StyleConstants.setFontFamily(lineStyle, "Verdana");
                  StyleConstants.setBold(lineStyle, true);
                  StyleConstants.setFontSize(lineStyle, 10);
                  //StyleConstants.setBackground(userStyle, Color.blue);
                  StyleConstants.setForeground(lineStyle, Color.DARK_GRAY);                
                  
                  errorStyle = messagesDoc.addStyle("errorStyle", null);
                  StyleConstants.setFontFamily(errorStyle, "Verdana");
                  StyleConstants.setBold(errorStyle, true);
                  StyleConstants.setFontSize(errorStyle, 10);
                  //StyleConstants.setBackground(userStyle, Color.blue);
                  StyleConstants.setForeground(errorStyle, Color.RED);          

            }
            return messagesJTP;
      }



--> This is where i append the message to the JTextPane


            if(messageNo != 0){
                  try{
                        messagesDoc.insertString(messagesDoc.getLength(), "\n"+"_____________________________________________\n", lineStyle);
                  }catch(Exception e){
                  }
            }
            // Append to document
            try{
                                    
                  
                  messagesDoc.insertString(messagesDoc.getLength(), "> " + fromUser, receiveUserStyle);
                  messagesDoc.insertString(messagesDoc.getLength(), "           " + Datum.getToday().toString() + " - " + Zeit.getActualTime().toString(), receiveTextStyle);
                  
                  // delete Button
                  JButton deleteItemJB = new JButton(getIconClose());
                  deleteItemJB.setSize(12,12);
                  deleteItemJB.setPreferredSize(new Dimension(12,12));
                  deleteItemJB.setLocation(78,1);
                  
                    deleteItemJB.addActionListener( new ActionListener() {
                    public void actionPerformed(ActionEvent e) {  
                          MessageMask.this.setVisible(false);
                    }
                    });
                    
                    
//                  The component must first be wrapped in a style
                  JButton addToFavoritesJB = new JButton(getIconMinimize());
                  addToFavoritesJB.setSize(12,12);
                  addToFavoritesJB.setPreferredSize(new Dimension(12,12));
                  addToFavoritesJB.setLocation(64,1);
                        
                        
                  JPanel containerJP = new JPanel();
                  containerJP.setPreferredSize(new Dimension(100,20));
                  containerJP.setLayout(null);
                  containerJP.add(deleteItemJB);
                  containerJP.add(addToFavoritesJB);
                  
                  // The component must first be wrapped in a style
                  Style style = messagesDoc.addStyle("buttonsStyle", null);
                  StyleConstants.setAlignment(style, StyleConstants.ALIGN_RIGHT);
                  StyleConstants.setComponent(style, containerJP);
                  
                  // Insert the component at the end of the text
                  messagesDoc.insertString(messagesDoc.getLength(), "ignored text", style);
                  
                                    
                  messagesDoc.insertString(messagesDoc.getLength(), "\n   " + message , receiveTextStyle);
                  

      
            }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></div></p>")
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(messagesDoc.getLength(), "\n"+"_____________________________________________\n", lineStyle);
--> 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
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16868459
0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16868473
> 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
0
 

Author Comment

by:qasinformatik
ID: 16868981
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(false);
            messagesJTP.setContentType("text/html");
            
            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.getAllMessages();
            
      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().toString() + " - " + msg.getReceiveTime().toString();
            code += "</div>\n";
            code += msg.getMessage().replaceAll("\n", "<br>\n");                  
            code += "\n";
            
            
      }
      code += "</body></html>";
      
      getMessagesJTP().setText(code);

--> 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("/qas/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?

0
 
LVL 14

Expert Comment

by:hoomanv
ID: 16869271
pane.addHyperlinkListener(new HyperlinkListener() {
    public void hyperlinkUpdate(HyperlinkEvent event) {
        ...
    }
});
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 16872129
hope hoomany's post helps regarding the hyperlink event!
0
 

Author Comment

by:qasinformatik
ID: 16893915
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.getAllMessages();
         
     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().toString() + " - " + msg.getReceiveTime().toString();
          code += "</div>\n";
          code += msg.getMessage().replaceAll("\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?

0
 

Author Comment

by:qasinformatik
ID: 16893926
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?
0
 

Accepted Solution

by:
CetusMOD earned 0 total points
ID: 17152187
PAQed with points refunded (500)

CetusMOD
Community Support Moderator
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Suggested Courses
Course of the Month18 days, 16 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question