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 JXHyperlinks (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);
alt text http://img187.imageshack.us/img187/3238/wraprn0.png
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 );
}
}
I found JTextPane, which I had overlooked before for some reason. This class does what I need.
Thanks for your help though. :)
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 a Container (such as Panel), it should be possible to have a Panel 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 for Panel) 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 a Container by using the add() method.
For example, have a class constant Component in the custom Layout Manager, such as (a hypothetical) LineBreakLayout.LINE_BREAK, and adding that to the Container 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 first Label in one line and the second Label in the second line.
Related
I have this code that seems to throw a IllegalComponentException, and I’m not sure why. It boils down to these lines of code:
JRadioButton setRed = new JRadioButton(“Red", true);
JRadioButton setBlue = new JRadioButton("Blue", false);
JRadioButton setYellow = new JRadioButton("Yellow", false);
JPanel options = new JPanel();
options.add(setBlue, BoxLayout.Y_AXIS);//error here
options.add(setRed, BoxLayout.Y_AXIS);//and probably here too
options.add(setYellow, BoxLayout.Y_AXIS);//and here
Here is the error:
Exception in thread "main" java.lang.IllegalArgumentException: illegal component position
at java.awt.Container.addImpl(Container.java:1034)
at java.awt.Container.add(Container.java:406)
at DrawCanvas.go(DrawCanvas.java:42)
at DrawCanvas.main(DrawCanvas.java:27)
Your code makes no sense. You don't use the BoxLayout constants when adding components to a JPanel, but rather you use the constants when creating your BoxLayout object, something that you've not yet done.
You need to:
Create a BoxLayout object using an appropriate BoxLayout constant, and passing in a reference to the container that will use this layout.
Set your JPanel's layout to this object
Add your components to the JPanel without constants.
Most importantly, you need to read the tutorial as it's obvious that you're trying to use this tool without first checking this important resource first. You can't guess at this stuff and expect it to work.
Google: Java BoxLayout tutorial. First hit.
I have made a frame in which i have put two jTextfield boxes where the user can see the path of the loaded file. Problem is that if the path is too long , the textfield expands to accomodate the full path which again leads to display problems. I would like to keep the textfield's length constant and instead , display the full path of file as a tooltip instead.
How can this be done?
Code for layout manager of jinternal Frame:
javax.swing.GroupLayout jInternalFrame1Layout = new javax.swing.GroupLayout(jInternalFrame1.getContentPane());
jInternalFrame1.getContentPane().setLayout(jInternalFrame1Layout);
I never use an IDE so I don't know how the GroupLayout works.
But when using the other layout managers I always use:
JTextField textField = new JTextField(10); // or whatever size your want
This will give the text field a preferred size and the layout manager can use that information when laying out the component.
Code the GUI by hand instead. You will avoid problems like this and it will be much easier to make changes to your code.
you need to choose a layout manager to manage the proportions of your JComponents.
Try to put your textfiels on a JPanel so you can select a layout useful for you
Later you can use JTextField. setToolTip("full path") to set a tool tip
I solved my problem:
Anybody having the same problem can set the Property Columns using Netbeans. The default is 0, so the textfield cannot accomodate the full text. Use some value like 3 to achieve it.
I'm running into a problem that I can't seem to figure out nor find the answer anywhere on the web.
I've got a JLayeredPane and when it only has one child Panel I am able to correctly set the cursor using setCursor(). The cursor shows up and everything is fine. But when I add an additional JPanel into the JLayeredPane the cursor no longer shows up
for example this works:
m_layeredPane = new JLayeredPane();
m_layeredPane.setLayout(new WBLayoutManager());
m_layeredPane.add(m_mediaPanel, new Integer(0));
// m_layeredPane.add(m_whiteboardPanel, new Integer(1));
m_layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // WORKS
but this doesn't:
m_layeredPane = new JLayeredPane();
m_layeredPane.setLayout(new WBLayoutManager());
m_layeredPane.add(m_mediaPanel, new Integer(0));
m_layeredPane.add(m_whiteboardPanel, new Integer(1));
m_layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // FAILS
Anyone know how i can get custom cursors working within a JLayeredPane
If you take a look at javax.swing.JLayeredPane source code, you will see its constructor defined like that:
public JLayeredPane() {
setLayout(null);
}
which clearly indicates that it needs to handle components layout by itself.
Hence you can guess (although it is not documented, I would consider it a documentation bug) that you should not change the layout of JLayeredPane.
While the topic is old, none of the answers was satisfying. I resolved the problem calling to the setCursor method of the JLayeredPane in this way:
this.getParent().setCursor( Cursor.getDefaultCursor() );
Where "this" is the component I want to change the cursor to. Its parent is the JLayeredPane (since it is added to it).
Works fine for me when using the demo code the the How to Use Layered Panes tutorial.
Based on the 3 lines of code the only difference I can see from the tutorial is that you are using a layout manager.
Compare your code with the tutorial to find other differences.
Have you tried taking the first working code, but placing the m_mediaPanel on level 1? This probably won't work either. I think this is due to the fact that the panel that is on top determines the cursor. On level 0 the layered pane itself can determine this.
I'm using Java Swing and I have the following problem:
I have a class TnaiPanel that extends JPanel. In this class I am creating 3 components and then lay them out in a horizontal line using a BoxLayout.
Also, I have a class TnaimDinamimPanel that also extends JPanel. This class contains multiple occurances of TnaiPanel, layed out vertically using a BoxLayout.
Also, I have a class MainFrame that extends JFrame. This frame contains a menu-bar and one main panel. The main panel can change (when choosing a certain menu-item, I create a new panel and set it to show as the main panel of the frame).
Now, for some reason I get "BoxLayout can't be shared" when I add the newly created TnaimDinamimPanel to the components of the frame.
I don't mind using different layout objects.
The result I want to get is a sort of "table" of components, where each TnaiPanel will have fixed component sizes and spacing, essentially serving the role os a "row" in the "table".
Thanks,
Malki.
You probably create only a single BoxLayout instance. Create a new one each time you need one (i.e. one per TnaiPanel, one per TnaimDinamimPanel and probably one per MainFrame).
To answer the second part of your question, ie "having a table of components", I would say that you can't do it with different panels, except if you start setting the individual min, pref and max sizes of components and panels, which is highly unadvised.
If you need to have correct alignment as in a table of components, then you need to put all your components in one panel, which also means you need to use only one layout. However, the only default swing layout that can allow you to do what you want is the GridBagLayout. Actually the GroupLayout (java 6) would also fit the bill but it absolutely requires a graphical designer (eg the one within netbeans).
If, like me, you are allergic to builders, then you'd better use one 3rd-party LayoutManager that is intended to be use programmatically (I would not consider GridBagLayout to be in this category although I have already used it that way in the past).
MigLayout (as suggested by Skeptic) is one option. Another option is DesignGridLayout which might fit your purpose better and is easier to use than MigLayout.
Try MiGLayout instead.
How do I create a horizontal JSeparator with a title label in Java Swing?
Something like this:
--- Title XYZ --------------------
I found a solution: SwingX JXTitledSeparator. We already use SwingX in our project. I didn't know that SwingX provides a titled separator.
#Bombe Thank you for your help.
Hmm… without any testing and completely from the top of my head:
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder("Title"));
menu.add(panel);
Most Swing containers eat anything so that might even work.
Another approach would be to create a custom component (maybe with a horizontal BoxLayout) and add a JSeparator, a JLabel, and another JSeparator to it, then add it to the menu.