Java SetIcon changing layout border of jLabel - java

I'm trying to create a kind of zoom whit the mouse wheel. Everytime i move the wheel, teoricaly both the jlable and the image change sizes according(im showing the width value).
Verifiable Example:
Whitout setIcon: Whit setIcon:
Img:144 Img:144
jLable:144 jLable:144
Img:160 Img:144
jLable:160 jLable:144
Img:176 Img:160
jLable:176 jLable:160
Img:192 Img:144
jLable:192 jLable:144
The problem happens when i try insert the image into the jframe:
jLabel1.setIcon(resizedImage);
Can anyone explain me this behavior? It seems for some reason setIcon uses the previous layout, instead of the correct one.
Minimal Version of code:
public void mouseWheelMoved(MouseWheelEvent e) {
int delta = 16 * (int)e.getPreciseWheelRotation();
Dimension factor = new Dimension(jLabel1.getWidth()+delta, jLabel1.getHeight()+delta);
jLabel1.setSize(factor);//force jlabel1 to get the new size
//Relocate Image
Image img = image.ScaleImage(factor);//Teoricaly give the image whit the new size
ImageIcon resizedImage = new ImageIcon(img);
//Gives the image to jlabel
jLabel1.setIcon(resizedImage);
}
});
Complete Version of Code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import pokemon.classes.BitmapController;
import pokemon.objects.ResizableImage;
import javax.swing.border.Border;
public class Aplicacao extends javax.swing.JFrame {
public Aplicacao() {
initComponents();
setExtendedState(JFrame.MAXIMIZED_BOTH);
///
BitmapController file = new BitmapController();
ResizableImage image = new ResizableImage(file.readImage());//reads the bmp image
ImageIcon icon = new ImageIcon(image.master);
jLabel1.setIcon(icon);
//Create the Controller for scroll effect
scrollController(image);
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Aplicacao().setVisible(true);
}
});
}
public void scrollController(ResizableImage image){
Border border = BorderFactory.createLineBorder(Color.BLUE, 5);
jLabel1.setBorder(border);
jLabel1.addMouseWheelListener(new MouseAdapter() {
public void mouseWheelMoved(MouseWheelEvent e) {
int delta = 16 * (int)e.getPreciseWheelRotation();
Dimension factor = new Dimension(jLabel1.getWidth()+delta, jLabel1.getHeight()+delta);
//jLabel1.setSize(factor);
//Relocate Image
//System.out.println("width: " + image.ScaleImage(factor).getWidth(rootPane));
Image img = image.ScaleImage(factor);
System.out.println("Img:"+img.getWidth(rootPane));
System.out.println("jLable:"+jLabel1.getWidth());
ImageIcon resizedImage = new ImageIcon(img);
jLabel1.setIcon(resizedImage);
}
});
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(68, 68, 68)
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(472, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(74, 74, 74)
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 256, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(143, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
}
////Class ResizableImage
import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;
public class ResizableImage {
public BufferedImage master;
private Image scaled;
public ResizableImage(BufferedImage master){
this.master=master;
}
public Image ScaleImage(Dimension size){
Image scaledImg = master.getScaledInstance(size.width, size.height,Image.SCALE_DEFAULT);
return scaledImg;
}
}
//Class BitmapController
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class BitmapController {
public BufferedImage readImage(){
BufferedImage image = null;
try{
image = ImageIO.read(new File("D:/Tileset42.bmp"));
//System.out.println("ola");
}catch (Exception ex){ System.out.println("error");}
return image;
}
}

Related

JPanel JFrame PaintComponent || Image is not being shown to JPanel

Please see the below code. I'm trying to display an image on the JPanel. Look at the screenshoot. I want to paint image over FrameImagePanel. but it is not working.
this.imagePanel = new ImagePanel();
FrameImagePanel.add(this.imagePanel);
FrameImagePanel.setSize(this.imagePanel.getWidth(), this.imagePanel.getHeight());
Look at the part above. this code was supposed to show the image. ?? some part of the code is not added here. as stackoverflow does not allow much details code.
enter image description here
package imagetopixelvalue;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
* #author MARUF AHMAD
*/
public class ViewImage extends javax.swing.JFrame {
public ImagePanel imagePanel;
/** Creates new form ViewImage */
public ViewImage() {
initComponents();
// JFrame frame = new JFrame("Testing");
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.imagePanel = new ImagePanel();
FrameImagePanel.add(this.imagePanel);
FrameImagePanel.setSize(this.imagePanel.getWidth(), this.imagePanel.getHeight());
System.out.print(" --> "+this.imagePanel.getWidth()+" || "+ this.imagePanel.getHeight());
// frame.pack();
// frame.setLocationRelativeTo(null);
// frame.setVisible(true);
}
public class ImagePanel extends JPanel {
int ImageH =0;
int ImageW =0;
BufferedImage imageBuff;
public ImagePanel(){
try{
BufferedImage image = ImageIO.read(new File("image.jpg"));
imageBuff = image;
System.out.print(image.getWidth()+" || "+ image.getHeight());
ImageH = image.getHeight();
ImageW = image.getWidth();
}
catch(IOException e){
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(ImageW, ImageH);
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.drawImage(imageBuff, 0, 0, this);
}
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
FrameImagePanel = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
FrameImagePanel.setBackground(new java.awt.Color(255, 255, 255));
javax.swing.GroupLayout FrameImagePanelLayout = new javax.swing.GroupLayout(FrameImagePanel);
FrameImagePanel.setLayout(FrameImagePanelLayout);
FrameImagePanelLayout.setHorizontalGroup(
FrameImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 380, Short.MAX_VALUE)
);
FrameImagePanelLayout.setVerticalGroup(
FrameImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 278, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(FrameImagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(FrameImagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ViewImage().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JPanel FrameImagePanel;
// End of variables declaration
}
you do not need to check all the code just see the above part.

How can I display an image in a JPanel

My question here is how can I display an image into a JPanel? Other topics here asking something similar aren't clear to my about how can I do that.
I have a directory in my project folder that have image files Project Folder/GUI/img, specifically gray.png and green.png which I want to display in a JPanel.
I tried with the following code using ImageIcon and JLabel that I found in other post:
ImageIcon image = new ImageIcon("GUI/img/gray.png");
JLabel label = new JLabel(image);
//JPanel panel is already initialized by the IDE
panel.add(label)
But doesn't work... The JPanel remain empty without displaying any image. How can I do that?
Additional to this, I want that the image inside the JPanel change (gray.png for green.png) when some action is performed, for example pressing a button. I can archive that by the same method for display the image in the JPanel right?
Thanks in advance!
EDIT: Here's an example of a test code for get this. The initialization is done automatically by the IDE.
import java.awt.Image;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class Sample extends javax.swing.JFrame {
public Sample() {
initComponents();
}
//Initialization
private void initComponents() {
PanelImage = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowOpened(java.awt.event.WindowEvent evt) {
formWindowOpened(evt);
}
});
javax.swing.GroupLayout PanelImageLayout = new javax.swing.GroupLayout(PanelImage);
PanelImage.setLayout(PanelImageLayout);
PanelImageLayout.setHorizontalGroup(
PanelImageLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 100, Short.MAX_VALUE)
);
PanelImageLayout.setVerticalGroup(
PanelImageLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 100, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(61, 61, 61)
.addComponent(PanelImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(239, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(45, 45, 45)
.addComponent(PanelImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(155, Short.MAX_VALUE))
);
pack();
}
private void formWindowOpened(java.awt.event.WindowEvent evt) {
try {
DisplayImage(PanelImage, "/GUI/img/gray.png");
} catch (Exception ex) {
Logger.getLogger(Sample.class.getName()).log(Level.SEVERE, null, ex);
}
}
//For display the url image in a JPanel
private void DisplayImage(JPanel jp, String url) throws IOException, Exception {
try {
Image image=ImageIO.read(this.getClass().getResource(url));
ImageIcon imageicon=new ImageIcon(image);
JLabel label=new JLabel(imageicon);
jp.add(label);
} catch (IOException ex) {
throw new IOException();
} catch (Exception ex) {
throw new Exception();
}
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Sample.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Sample().setVisible(true);
}
});
}
// Variables declaration
private javax.swing.JPanel PanelImage;
}
The private void DisplayImage(JPanel jp, String url) is what I need to work for display the image, from the url String url in the JPanel jp
Looking for pieces of code in Google I ended up with a solution... And was applying the same pattern that previous comments refer.
The code that gave me the solution was:
label.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/gray.png")))
With that, I made then the method that I wanted to implement:
private static void DisplayImage(JPanel jp, String url) {
JLabel jl=new JLabel();
jl.setIcon(new javax.swing.ImageIcon(getClass().getResource(url)));
jp.add(jl);
}
Maybe this is not the perfect and most-correct solution, but works perfect to my, that is what I want.
Thanks all for the answers and suggestions!
I had a similar issue when I was working on creating Minesweeper. I ended up finding a solution and getting it to work by first loading an Image and then creating an ImageIcon from that Image.
Image myImage = ImageIO.read(getClass().getResource("image_path.jpg"));
myImage = myImage.getScaledInstance(30, 30, java.awt.Image.SCALE_SMOOTH);
ImageIcon myImageIcon = new ImageIcon(myImage);
you have to use ImageIcon(this.getClass().getResource("/Gui/img/gray.png"));
here is example its working.
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ExImage extends JPanel
{
public ExImage()
{
ImageIcon imageIcon = new ImageIcon(this.getClass().getResource("/gray.png"));
JLabel label = new JLabel(imageIcon);
add(label);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new ExImage());
frame.setVisible(true);
frame.setPreferredSize(new Dimension(200, 300));
}
}

JTree refresh without collapsing

I have a problem when refreshing a JTree instance. See the following code:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class ItemTest {
private JFrame frame;
private DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
private JTree tree = new JTree(root);
private JButton button = new JButton("Rebuild");
private String[] array = new String[] { "name", "first_name", "middle_name", "last_name"};
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
ItemTest window = new ItemTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ItemTest() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 523, 349);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scrollBar = new JScrollPane();
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(scrollBar, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
.addComponent(button, GroupLayout.PREFERRED_SIZE, 85, GroupLayout.PREFERRED_SIZE)
.addContainerGap(412, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(22)
.addComponent(scrollBar, GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
.addComponent(button, GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE)
.addContainerGap())
);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
root.add(new DefaultMutableTreeNode("Row 4"));
((DefaultTreeModel) tree.getModel()).nodeChanged(root);
}
});
for(String string : array) {
root.add(new DefaultMutableTreeNode(string));
}
scrollBar.setViewportView(tree);
frame.getContentPane().setLayout(groupLayout);
}
}
If we run this code, and expand the "Root" node. We will see 4 nodes in it. If we click the button "Rebuild", the tree won't update it's self. The weird thing is, if we don't expand the "Root" node at the begin (so just start the application) and click the button, and after that we expand the "Root" node, the new row is added. Does anyone knows how to refresh this tree without collapsing, because nodeChanged doesn't seem to work when you expand the "Root" node at the begin.
Note: I have to accomplish this without using insertNodeInto.
You must notify the listeners that a node was inserted:
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
root.add(new DefaultMutableTreeNode("Row 4"));
((DefaultTreeModel) tree.getModel()).nodesWereInserted(
root, new int[]{root.getChildCount()-1});
}
});

JScrollPane and autoscroll: Disturbing scrolling behavior

I am writing an application which uses a JScrollPane. In this JScrollPane I want to automatically display search results, This means, that I have to dynamically add and remove the results within the JScrollPane. The results are realised as JTextArea, which are embeded within a GridBagLayout.
When there is a high number of search results, the JScrollPane automatically scrolls to the bottom (It should be at the top). I have solved it with a solution I found here. The problem hereby is, that you can see, how it scrolls back to the top. Is it possible to remove this behaviour?
The following things I found out:
I have to remove the previous search results to display the new ones. If I don't remove the previous ones, it displays correctly.
It neither solves the prblem wgeb I update the JScrollPane every tune after adding arow nor when updating only after adding all rows.
The best would be to just disable autoscroll. I have created an executable example to demonstrate this behavior. When clicking the button "Add Row", 500 rows are added. When clicking it several times, it becomes very clear.
Thank you very much for your help!
import java.awt.GridBagConstraints;
import javax.swing.JTextArea;
public class ScrollPaneTest extends javax.swing.JFrame {
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
/**
* Creates new form ScrollPaneTest
*/
public ScrollPaneTest() {
initComponents();
}
/**
* Adds a new row.
* #param index The index of the new row.
*/
private void addRow(int index) {
JTextArea row = new JTextArea("Area " + index);
row.setEditable(false);
row.setBorder(null);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = index;
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
jPanel2.add(row, gridBagConstraints);
}
/**
* Initializes the components.
*/
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel();
jPanel2 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 400));
jScrollPane1.setViewportView(jPanel1);
jPanel1.setLayout(new java.awt.BorderLayout());
jPanel2.setLayout(new java.awt.GridBagLayout());
jPanel1.add(jPanel2, java.awt.BorderLayout.NORTH);
jScrollPane1.setViewportView(jPanel1);
jButton1.setText("Create Rows");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addGap(148, 148, 148)
.addComponent(jButton1)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 245, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton1)
.addGap(0, 21, Short.MAX_VALUE))
);
pack();
}
/**
* Creates 500 new rows.
* #param evt
*/
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jPanel2.removeAll();
for(int i = 0; i < 1000; i++) {
addRow(i);
}
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
jScrollPane1.getVerticalScrollBar().setValue(0);
}
});
jPanel2.validate();
jPanel2.repaint();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ScrollPaneTest().setVisible(true);
}
});
}
}
UPDATE 1
I removed the lambda expressions. Hopefully it should be now compileable also with < Java 8.
UPDATE 2
The problem with the disturbing scrolling behavior has been solved by replacing
jPanel2.validate();
jPanel2.repaint();
with
jScrollPane1.validate();
jScrollPane1.repaint();
Nevertheless, both answers to this question can be very helpful in some other cases and should be given attention.
One way to achieve this is to have a custom JViewPort for your scrollpane. This custom viewport overrides setViewPosition and uses a flag to prevent the scroll, or not.
Here is an example of such code, before changing the content of the textarea, we "lock" the viewport to prevent scrolling, and we unlock it later:
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TestNoScrolling {
private int lineCount = 0;
private LockableViewPort viewport;
private JTextArea ta;
private final class LockableViewPort extends JViewport {
private boolean locked = false;
#Override
public void setViewPosition(Point p) {
if (locked) {
return;
}
super.setViewPosition(p);
}
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
}
protected void initUI() {
JFrame frame = new JFrame("test");
ta = new JTextArea(5, 30);
JScrollPane scrollpane = new JScrollPane();
viewport = new LockableViewPort();
viewport.setView(ta);
scrollpane.setViewport(viewport);
frame.add(scrollpane);
frame.pack();
frame.setVisible(true);
Timer t = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
viewport.setLocked(true);
ta.append("Some new line " + lineCount++ + "\n");
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
viewport.setLocked(false);
}
});
}
});
t.setRepeats(true);
t.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestNoScrolling().initUI();
}
});
}
}
You could simply set the Caret position to the start position (0), for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ScrollNoMore {
public static void main(String[] args) {
new ScrollNoMore ();
}
public ScrollNoMore () {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
private JScrollPane sp;
private Random rnd = new Random();
private boolean initalised = false;
public TestPane() {
setLayout(new BorderLayout());
ta = new JTextArea(20, 40);
sp = new JScrollPane(ta);
add(sp);
Timer timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
long value = rnd.nextLong();
ta.append(String.valueOf(value) + "\n");
if (!initalised) {
ta.setCaretPosition(0);
initalised = true;
}
}
});
timer.start();
}
}
}
This will only set it the first time the Timer runs, this means that if you move the Caret or scroll position for some reason, it won't "flick" back. You could set up a series of states where by if the user moved the current view, it didn't effect the scrolling, but could be reset as required.

JPanel cropping or (.setBounds()) not working

Sometimes the setBounds() works but only in the actionlistener.
my code:
-does not work
public panel() {
initComponents();
setBounds(100,100,105,105);
setMaximumSize(new Dimension(100,100));
}
-does work
private void btnBestellingItemToevActionPerformed(java.awt.event.ActionEvent evt) {
setBounds(100,100,105,105);
setMaximumSize(new Dimension(100,100));
}
-layout manager:
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnBestellingItemToev, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(txtWat, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(txtTafelNr, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)))
.addGap(0, 131, Short.MAX_VALUE))
);
Can anyone help me so it works in the constructor also?
As I said, the problem you're having is the fact that the container the component you are trying to move/size has a layout manager on it.
The layout manager is responsible for determining the position and size of all the components within in it.
You have two choices. Write your own layout manager that does what you want it to do. This is reasonably complex process, but is generally a better choice or do without a layout manager.
Personally, when doing things like this, I paint the result directly to the panel, but that's me...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class BouncyBall {
public static void main(String[] args) {
new BouncyBall();
}
public BouncyBall() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BallCourt());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BallCourt extends JPanel {
private JLabel beachBall;
private int delta = 4;
public BallCourt() {
setLayout(null);
beachBall = new JLabel();
try {
beachBall.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/BeachBallOfDoom.png"))));
} catch (IOException ex) {
ex.printStackTrace();
}
beachBall.setBounds(0, 100 - 16, 32, 32);
add(beachBall);
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int x = beachBall.getX() + delta;
if (x + beachBall.getWidth() > getWidth()) {
delta *= -1;
x = (getWidth() - beachBall.getWidth()) + delta;
} else if (x < 0) {
delta *= -1;
x = delta;
}
beachBall.setLocation(x, beachBall.getY());
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

Categories

Resources