i used textarea1.setVisible(false); but still i can see the border of the text area at run time. i want the textarea to be completely invisible
Can anyone help in this issue?
It sounds like you have a Panel around your text area since setVisible(false) should definitely hide the entire component. If so, make the panel invisible. Care to post some code so we can examine and help?
You have to hide the scroll pane which your text area is sitting in. If for some reason you have no direct access to it here is the way to get it:
public static final JScrollPane getScrollPane( JComponent component ) {
Container p = component .getParent();
if (p instanceof JViewport) {
Container gp = p.getParent();
if (gp instanceof JScrollPane) {
return (JScrollPane)gp;
}
}
return null;
}
Find your textarea scrollpane, then set the visibility to false, like this:
jScrollPane4.setVisible(false);
Related
I have several JtextPanes and I want to create a method that set the value of a variable to the name of the TextPane which has been clicked because another methond is going to use it. There's also a button that adds a new jTextPane when the user clicks on it and I want those new TextPanes to inherit that method. Or if you know a simpler way to achieve that I'm open to read you. Let me know if you need more information or more code.
static JTextPane focus;
private void redColorActionPerformed(java.awt.event.ActionEvent evt) { //Ths is the method that works with the focus variable. It changes the color of the text in the clicked textpane.
TextEditor.cambiarColor(new java.awt.Color(255, 0, 0), focus);
}
It sound like you want to know the current Swing JTextPane component under the current mouse position? Then try to
Get current Mouse position
Point position = MouseInfo.getPointerInfo().getLocation();
Get the component under the mouse location
Component c = SwingUtilities.getDeepestComponentAt(
the-root-component,
position.getX(),
position.getY()
);
if (c instanceof JTextPane) {
// do your logic
}
I have a JScrollPane containing a JPanel. I fill this JPanel with many buttons.
Is there any possibility to get the currently shown buttons?
I know I can access the children of a JPanel via jpanel.getComponents() but those are all components in this pane; I want only the ones that are currently on screen.
As already commented to #mKorbel's answer:
it's correct that you need the child bounds
it's correct that you need to intersect those bounds with "something"
it's wrong that you need the containing viewport (nor the scrollpane)
JComponents have an API to get their currently visible part independently of how/where exactly they are currently shown, so the "something" is the JComponent's visibleRect:
Rectangle visibleRect = myPanel.getVisibleRect();
for (Component child : myPanel.getComponents()) {
Rectangle childBounds = child.getBounds();
if (childBounds.intersects(visibleRect)) {
// do stuff
}
}
I assume that this container is already visible on the screen, then I suggest
1) to extract JViewPort from JScrollPane,
2) addChangeListener to JViewPort
3) each visible JComponent(s) returns Rectangle
4) and Rectangle#intersects returns Boolean value if is JComponent(s) visible or not in JViewPort
How about asking the components if they're visible:
for ( Component component : jpanel.getComponents() ) {
if ( component instanceof JButton && component.isShowing() ) {
// We've found a button that is showing...
}
}
Component#isShowing()
scrollPane.getViewport().getView()
scrollPane.getViewport().getViewRect()
With this code I am able to find what tab is selected but I need to do stuff with what is inside the tab. How do I work with the hierarchy?
EditPane.addChangeListener(new ChangeListener() {
// This method is called whenever the selected tab changes
public void stateChanged(ChangeEvent evt) {
JTabbedPane pane = (JTabbedPane)evt.getSource();
// Gets current tab
int sel = pane.getSelectedIndex();
}
});
The component that is inside the tab is a JScrollPane.
You don't need the index of the pane, you need the component selected underneath.
use getSelectedComponent() - e.g.
JTabbedPane pane = (JTabbedPane)evt.getSource();
JComponent myComponent = pane.getSelectedComponent();
To clarify your original goal, you want to manipulate the client object living in the JScrollPane. You're missing some objects.
in your JScrollPane you need to invoke getViewport().getViewportView() from the ScrollPane. (Source: http://download.oracle.com/javase/tutorial/uiswing/components/scrollpane.html )
# Dasdasd
I already checked it out but it only returns ViewPorts and ScrollBars
yes that correct, (probalby there you put JPanel) then you have to repeats your steps again, until as you will not find JPanel into ViewPort, that's possible get JComponents another way(s), but this is very good lesson for Hierarchy of JComponents
Component[] components = xxx.getComponents();
for (int i = 0, l = components.length; i < l; i++) {
if (components[i] instanceof JScrollPane) {
JScrollPane scr = (JScrollPane) components[i];
Component[] components1 = scr.getComponents();n
I am trying to implement a JScrollPane with a JTextArea. The JTextArea is being appended to, and I want the JScrollPane to keep scrolling down as more text is added. How can this be achieved?
For (what I think is) a simpler answer check out: Text Area Scrolling.
Prior to JDK5, you would have to manually change the caret's position after each append. You can now give this behaviour as a default like this :
JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
The advantage of this is that you don't need to use this snippet more than once in your code!
I found the answer here:
JScrollPane and JList auto scroll
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
If you are constantly writing data to it you could use:
textArea.setCaretPosition(textArea.getDocument().getLength());
just after you add the new data.
This would automatically scroll all the way down the JScorllPane.
Here is the solution.
JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);`
The accepted solution works good, but only when the text area is editable, i.e. without jTextArea.setEditable(false) . The solution suggested by Krigath is more general, but has the problem as asked here JScrollPane and JList auto scroll. Using answers from that question you can get general solution, e.g.:
JScrollPane scrollPane = new JScrollPane(jTextArea);
verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
scrollPane.getVerticalScrollBar().addAdjustmentListener(
e -> {
if ((verticalScrollBarMaximumValue - e.getAdjustable().getMaximum()) == 0)
return;
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
});
The Pane then is scrolled down only when vertical scroll bar is expanding, in response to appended lines of text.
I admit that that a method to filter events without extra variables could be found, and would appreciate if somebody post it.
A work around is possible: you can declare that listener as a class then instantiate it on the event where it is needed. After which you can remove the class after forcing a repaint of the screen. Works like a charm.
I was look at the answers and found that #user9999 answer is a good solution for those who want the scrollbar continuously scroll. I edited the code, got rid of the variable. It make the scrolling stop - when the user is scrolling manually. If the user scrolls to the end of the textarea or scrollarea, the auto scrolling continues.
(also as #user9999 suggested i removed the variable and added the jScrollPane1.getHeight() as the measure value to stop scrolling if the current scrollbar value is lower than max)
Here is the workaround:
jScrollPane1.getVerticalScrollBar().addAdjustmentListener(
e -> {
if ((e.getAdjustable().getValue() - e.getAdjustable().getMaximum()) > -jScrollPane1.getHeight() - 20){
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
Edit:
Added -20 to the -jScrollPane1.getHeight() - 20 as it is sometimes doesnt scroll without it, i guess the -20 can be changed depends on the font size of the TextArea.
Be careful if you're about to use auto scroll within a multithreaded program.
Like for example if somewhere is a method like
public void addNewLine(String s){
textPane.setText(textPane.getText()+"\n"+s);
if(autoscrollCheckBox.isSelected()){
this.revalidate();
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
}
}
You will get the following exception, if the addNewLine (or the vertical.setValue(...)) method is called from another thread. (Especially, if you're try to resize the window or try to scroll while, autoscroll is enabled)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.text.BoxView.calculateMajorAxisRequirements(BoxView.java:871)
at javax.swing.text.BoxView.checkRequests(BoxView.java:930)
at javax.swing.text.BoxView.getMinimumSpan(BoxView.java:568)
...
The reason for this is, the multithreaded call of the method is messing up with Swings' eventhandling, so you'll get random results or like above an error (read morehere).
The correct way is to call SwingUtilities.invokeLater(...):
public void addNewLine(String s){
SwingUtilities.invokeLater( () -> {
textPaneOutput.setText(textPaneOutput.getText()+"\n"+s);
if(autoscrollCheckBox.isSelected()){
this.revalidate();
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
}
});
}
This way you'll able to auto scroll threadsafe!
I'm having a problem. I want to put an image inside a form in Java and I don't know if I'm using a proper technique (found it somewhere in a web page).
private void iconSelect() {
String iconString = "";
if (typeCombobox.getSelectedIndex() == 0) {
iconString = "LP_";
} else if (typeCombobox.getSelectedIndex() == 1) {
iconString = "HP_";
} else if (typeCombobox.getSelectedIndex() == 2) {
iconString = "BP_";
} else if (typeCombobox.getSelectedIndex() == 3) {
iconString = "BS_";
}
if (RB_Gain_Clean.isSelected()) {
iconString = iconString + "Clean";
} else if (RB_Gain_dB.isSelected()) {
iconString = iconString + "dB";
}
ImageIcon icon = new ImageIcon("images/" + iconString + ".jpg");
Image img = icon.getImage();
if (iconGraphLabel.getWidth() > 0 && iconGraphLabel.getHeight() > 0) {
img = img.getScaledInstance(iconGraphLabel.getWidth(), iconGraphLabel.getHeight(), java.awt.Image.SCALE_SMOOTH);
}
icon = new ImageIcon(img);
iconGraphLabel.setIcon(icon);
}
So it actually shows the image and it is resizing but when I resize my form and then make it smaller again, the label doesn't seem to follow the resizing so it stays bigger than the window.
Also, since I'm not very familiar with java's graphics, can anyone tell me how can I control a window resizing event so I redraw the picture? Right now the method is triggered by the combobox and the radiobuttons shown in the code.
Thanks in advance!
edit1: Well the form is my jFrame. The iconGraphLabel is the jLabel I'm putting the image in. I'll try to explain the hierarchy of the parent components.
PlotArea [jPanel] (cardLayout) > plotArea_Image [jPanel] ("cardDraw") > iconGraphPanel [jPanel] > iconGraphLabel
but when I resize my form and then
make it smaller again, the label
doesn't seem to follow the resizing so
it stays bigger than the window
Correct, a JLabel, or any Swing component that uses Icons will paint the Icon at its actual size. If you want the Icon to scale depending on the space available then you need to do custom painting.
The Background Panel classes provides different options for displaying an image (you can just use the Icon,getImage() method). You should also read the section from the Swing tutorial on Custom Painting to better understand how the above code works.
Found a solution. This is the final code:
private void iconSelect() {
iconGraphPanel.removeAll();
ImageIcon icon = new ImageIcon("image.jpg");
BackgroundPanel imagePanel = new BackgroundPanel(icon.getImage(), BackgroundPanel.SCALED);
iconGraphPanel.add(imagePanel);
iconGraphPanel.revalidate();
}
iconGraphPanel is a common jPanel that I use as a place holder. It needs to be set to BorderLayout. The BackgroundPanel class can be found here. The removeAll() is needed so the old image disappears. If you don't put this images start to stack up. Don't know if there is a better way to do that but it works just fine for me. The revalidate() method is needed because we create a new panel so it needs to refresh.
This is mostly camickr work and some other guy from sun forum named Maxideon. I'm just posting for future reference.