How to implement a panel that would support line wrapping and line breaking? I would only add textual labels and line breaks to this panel. The labels should flow from left to right, wrapping to the next "line" if needed. The line breaks would cause a jump to the next line. I would also like to make the panel vertically scrollable.
The solution should work in Java 5. SwingX can be used.
Clarification: The textual labels are actually JXHyperlink
s (from SwingX),
i.e. the panel contains clickable labels. This is the reason I cannot just use
JTextArea
.
-
UPDATE: I missed the request for hyperlink support. Don't know how to do that w/o using the EditorPane.
JTextArea does exactly what you've described.
JTextArea textArea = new JTextArea(); JScrollPanel sPane = new JScrollPane(textArea);
Kaarel : I want to make the labels clickable, so that they could behave like hyperlinks. Could I do it with TextArea? (I don't want to use the JEditorPane with HTML.)basszero : Any reason against the JEditorPane (I'm just curious)?Kaarel : Seemed to be slow, and an overkill. Also I couldn't figure out how to store a Java object with each hyperlink on the page, so that clicking on the link would do some action based on the object.basszero : The Hyperlink event listener calls back with the Element and URL from anchor tag which caused the hyperlink. You could probably create some sort of mapping from URL->Object to take actionsKaarel : Right, I currently have something like that. I'm just wondering if there is a better solution, without such a mapping table.basszero : ahhh good deal. Now you've got me interested in the solution ;)OscarRyz : Do you really don't know how to store an object for the hiperlink? In java there is a data structure named: "Map" with various subclasses. You can have map.put( aLink, anObject ); and get the object when some link is used. It seems to me very straight forward. -
Although it may not be a solution you're in search of, but from the requirements you have, it seems like a custom
LayoutManager
may be able to achieve what you are after. By designing and assigning a custom Layout Manager which allows line breaks to aContainer
(such asPanel
), it should be possible to have aPanel
which allows line breaks.The Laying Out Components Within a Container article from The Java Tutorials will provide general information on how Layout Managers work in Java, and in particular, the Creating a Custom Layout Manager will provide information on how to make a custom Layout Manager to apply to an
Container
.The behavior of the
FlowLayout
(the default Layout Manager forPanel
) seems fairly close to the behavior you may be after. Adding functionality to line break seems like the missing piece.Suggestion: Perhaps the custom Layout Manager can have the ability to add a line break by having a
Component
that represents a line break, which can be added to aContainer
by using theadd()
method.For example, have a class constant
Component
in the custom Layout Manager, such as (a hypothetical)LineBreakLayout.LINE_BREAK
, and adding that to theContainer
can tell the custom layout manager to move to the next line. Perhaps an implementation can be like:Panel p = new Panel(new LineBreakLayout()); p.add(new Label("First Line")); p.add(LineBreakLayout.LINE_BREAK); p.add(new Label("Second Line"));
The above hypothetical
LineBreakLayout
will then render the firstLabel
in one line and the secondLabel
in the second line. -
This sample is not from a panel, that is a container, but from a JLabel, that is intended to show content.
You could use HTML in your content and use a <br> on each break. You should programmatically calculate the breaks according with your rules on component resize.
Here's the code:
import javax.swing.*; import java.awt.*; public class Wrap { public static void main( String [] args ) { JFrame frame = new JFrame("Wrap test"); String text = "<html>This<br>is<br>a<br>multiline<br>label</html>"; frame.add( new JLabel( text ) ); frame.pack(); frame.setVisible( true ); } }
OscarRyz : As per the hyperlinks you can have the by using a mouse listener. You can get where the object has been clicked and use a map to execute the action. But as reading your comments on basszero answer, I think you just don't feel like program it.Kaarel : Yes, I don't feel like implementing a map that would map strings to objects. I can use JXHyperlink (from SwingX) to store an object "into the link" and have an action performed on the object when the link is clicked. The problem is only how to layout the links so that they wrap in a scrollable pane. -
I found
JTextPane
, which I had overlooked before for some reason. This class does what I need.Thanks for your help though. :)
0 comments:
Post a Comment