Code in Question:
textArea.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
posX = e.getX();
posY = e.getY();
}
});
textArea.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
setLocation(e.getXOnScreen() - posX, e.getYOnScreen() - posY);
}
});
Background:
I have a JFrame, in that JFrame there is a JScrollPane, and in the JScrollPane there is a JTextArea called "textArea". This JTextArea take up the entire JFrame and the JFrame is undecorated. So to give some perspective, here is generally what the JFrame looks like...
When the mouse clicks within the JTextArea and moves, the entire window is dragged. Everything is setup to not be focus able for this work, it's meant to be an overlay.
Issue:
The code listed above works fine and the world is at peace. But once there is enough text for the vertical scroll bar to appear (There is no horizontal because of line wrapping), dragging the window becomes an issue. When you click and just begin to move, the JFrame instantly moves much higher on the screen. The lines in JTextArea, the higher it moves up when you try to move it. I assume that the get*OnScreen() methods are issue because it's all relevant to the JTextArea.
Class in Question:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main extends JFrame {
private JTextArea textArea;
private JScrollPane textAreaScroll;
private int posX = 0;
private int posY = 0;
public Main() {
initComponents();
initListeners();
for(int i = 0; i < 20; i++){
addLine(i+" Hello");
}
}
public void addLine(String line){
textArea.append("\n> "+line);
textArea.setCaretPosition(textArea.getDocument().getLength());
}
private void initListeners(){
textArea.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
posX = e.getX();
posY = e.getY();
}
});
textArea.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
setLocation(e.getXOnScreen() - posX, e.getYOnScreen() - posY);
}
});
}
private void initComponents() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {}
textAreaScroll = new JScrollPane();
textArea = new JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setUndecorated(true);
setAlwaysOnTop(true);
setAutoRequestFocus(false);
setBackground(new Color(130,210,255,130));
setFocusCycleRoot(false);
setFocusable(false);
setFocusableWindowState(false);
setName("main");
setOpacity(0.4f);
setResizable(false);
textAreaScroll.setBorder(null);
textAreaScroll.setFocusable(false);
textAreaScroll.setRequestFocusEnabled(false);
textArea.setEditable(false);
textArea.setBackground(new Color(0, 0, 0));
textArea.setColumns(20);
textArea.setFont(new Font("Consolas", 0, 14));
textArea.setForeground(new Color(255, 255, 255));
textArea.setLineWrap(true);
textArea.setRows(5);
textArea.setText("> Hello world!\n> another line!");
textArea.setBorder(null);
textArea.setFocusable(false);
textArea.setRequestFocusEnabled(false);
textAreaScroll.setViewportView(textArea);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textAreaScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textAreaScroll, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 214, Short.MAX_VALUE)
);
pack();
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Main().setVisible(true);
}
});
}
}
Well your diagnosis was absolutely spot on:
When you click and just begin to move, the JFrame instantly moves
much higher on the screen. The lines in JTextArea, the higher it moves
up when you try to move it. I assume that the get*OnScreen() methods
are issue because it's all relevant to the JTextArea.
So to resolve this use GlassPane of JFrame to attach MouseXXXListeners thus we can get correct co-ordinates when dragging, the main problem with this solution is glasspane will consume events that are meant for other components on JFrame, this can be overcome by redispatching the MouseEvents appropriately):
Create JPanel (this glassPane/JPanel will be transparent via setOpaque(false)), attach xxxAdapters here.
Create custom listener class to redispacth MouseEvents to the necessary components (as glasspane will consume all events to the JTextArea/JScollPane)
Set JPanel as GlassPane of your JFrame via JFrame#setGlassPane(..) .
set JFrame visible than set glassPane visible via setVisible(true) (this has been a Swing glitch for some time if you set it visible before the frame is visible it wont be shown).
Here is your fixed code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.MouseInputAdapter;
public class Main extends JFrame {
private JTextArea textArea;
private JScrollPane textAreaScroll;
private JPanel glassPane;//create variable for glasspane
public Main() {
initComponents();
initListeners();
for (int i = 0; i < 20; i++) {
addLine(i + " Hello");
}
}
public void addLine(String line) {
textArea.append("\n> " + line);
textArea.setCaretPosition(textArea.getDocument().getLength());
}
private void initListeners() {
GlassPaneListener gpl = new GlassPaneListener(textAreaScroll.getVerticalScrollBar(), this);
//add the adapters/listeners to the glasspane
glassPane.addMouseMotionListener(gpl);
glassPane.addMouseListener(gpl);
}
private void initComponents() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
}
textAreaScroll = new JScrollPane();
textArea = new JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setUndecorated(true);
setAlwaysOnTop(true);
setAutoRequestFocus(false);
setBackground(new Color(130, 210, 255, 130));
setFocusCycleRoot(false);
setFocusable(false);
setFocusableWindowState(false);
setName("main");
setOpacity(0.4f);
setResizable(false);
textAreaScroll.setBorder(null);
textAreaScroll.setFocusable(false);
textAreaScroll.setRequestFocusEnabled(false);
textArea.setEditable(false);
textArea.setBackground(new Color(0, 0, 0));
textArea.setColumns(20);
textArea.setFont(new Font("Consolas", 0, 14));
textArea.setForeground(new Color(255, 255, 255));
textArea.setLineWrap(true);
textArea.setRows(5);
textArea.setText("> Hello world!\n> another line!");
textArea.setBorder(null);
textArea.setFocusable(false);
textArea.setRequestFocusEnabled(false);
textAreaScroll.setViewportView(textArea);
textAreaScroll.setPreferredSize(new Dimension(200, 200));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textAreaScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textAreaScroll, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 214, Short.MAX_VALUE));
//create and make glasspane not opaque
glassPane = new JPanel();
glassPane.setOpaque(false);
//set glasspane as JFrame glassPane
setGlassPane(glassPane);
pack();
setVisible(true);//set JFrame visible
//glassPane can only be setVisible after JFrame is visible
glassPane.setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Main();
}
});
}
}
class GlassPaneListener extends MouseInputAdapter {
private int posX = 0;
private int posY = 0;
Toolkit toolkit;
private final Container contentPane;
private final Component textAreaScroll;
private final Component glassPane;
private final JFrame frame;
private boolean wasClickOnInterestedComponent = false;
public GlassPaneListener(Component textAreaScroll, JFrame frame) {
toolkit = Toolkit.getDefaultToolkit();
this.textAreaScroll = textAreaScroll;
this.frame = frame;
this.glassPane = frame.getGlassPane();
this.contentPane = frame.getContentPane();
}
#Override
public void mouseDragged(MouseEvent e) {
if (!redispatchMouseEvent(e)) {
frame.setLocation(e.getXOnScreen() - posX, e.getYOnScreen() - posY);
}
}
#Override
public void mousePressed(MouseEvent e) {
if (!redispatchMouseEvent(e)) {//check if event was redispatched if not its meant for us :)
posX = e.getX();
posY = e.getY();
}
}
#Override
public void mouseReleased(MouseEvent me) {
wasClickOnInterestedComponent = false;
}
private boolean redispatchMouseEvent(MouseEvent e) {
Point glassPanePoint = e.getPoint();
Container container = contentPane;
Point containerPoint = SwingUtilities.convertPoint(glassPane, glassPanePoint, contentPane);
// The mouse event is probably over the content pane.
// Find out exactly which component it's over.
Component component = SwingUtilities.getDeepestComponentAt(container, containerPoint.x,
containerPoint.y);
if ((component != null) && (component.equals(textAreaScroll)) || wasClickOnInterestedComponent) {
wasClickOnInterestedComponent = true;//so that if we drag iur cursor off JScrollBar tghe window wont be moved
// Forward events over the scrollbar
Point componentPoint = SwingUtilities.convertPoint(glassPane, glassPanePoint, component);
component.dispatchEvent(new MouseEvent(component, e.getID(), e.getWhen(), e.getModifiers(),
componentPoint.x, componentPoint.y, e.getClickCount(), e.isPopupTrigger()));
return true;//the event was redispatched
} else {
return false;//event was not redispatched
}
}
}
You are saying JFrame instantly moves much higher on the screen. The lines in JTextArea but actually it is scrolled down so only last few lines are visible.
If you would like to see textArea content from top, change is here
initComponents();
initListeners();
for (int i = 0; i < 20; i++) {
addLine(i + " Hello");
}
//set scrolling position to top
textArea.setCaretPosition(0);
Related
I'm student studying java swing. And I tried to programming simple program.
What I want is a notepad program that toggles between transparent and opaque when you press Ctrl+Alt.
Now press Ctrl + Alt to toggle between transparent and opaque. However, the font in transparent mode also changes. I used the SetFont () function to force the font to be set, but it only applies in opaque mode and the setFont function does not work in transparent mode.
If I remove setBackground () from the toggleVisible () function, the font will not change either. My guess seems to change the setBackground font. Anyone who knows how to make a frame transparent without using setBackground? Or I would appreciate it if you could help me solve the problem.
package ffmemo;
import java.awt.Color;
import java.awt.Font;
import java.awt.GraphicsDevice;
import static java.awt.GraphicsDevice.WindowTranslucency.TRANSLUCENT;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.BitSet;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class FFMemo {
public static void main(String[] args){
new FFMemoFrame();
}
}
class FFMemoFrame extends JFrame {
BitSet keyBitSet = new BitSet(2); //0: ctrl key, 1: alt key
boolean visible = true;
JTextArea textArea;
JScrollPane scrollPane;
Color color;
FFMemoFrame(){
//PARAM: window title
super("FFMemo");
setSize(500, 200);
setLocation(100, 100);
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
color = getBackground();
textArea = new JTextArea();
textArea.getDocument().addDocumentListener(new DocumentListener(){
#Override
public void changedUpdate(DocumentEvent e){
warn();
}
#Override
public void insertUpdate(DocumentEvent e) {
warn();
}
#Override
public void removeUpdate(DocumentEvent e) {
warn();
}
public void warn(){
//System.out.println(textArea.getText());
repaint();
}
});
textArea.append("hello, world!");
textArea.setLineWrap(true);
textArea.setVisible(true);
textArea.setFont(new Font("굴림", Font.PLAIN, 20));
textArea.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
String s = e.getKeyText(e.getKeyCode());
if(s.equals("Ctrl")) keyBitSet.set(0, true);
else if(s.equals("Alt")) keyBitSet.set(1, true);
if(keyBitSet.get(0) && keyBitSet.get(1)){
toggleVisible();
}
}
public void keyReleased(KeyEvent e){
String s = e.getKeyText(e.getKeyCode());
if(s.equals("Ctrl")) keyBitSet.set(0, false);
else if(s.equals("Alt")) keyBitSet.set(1, false);
}
});
scrollPane = new JScrollPane(textArea);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVisible(true);
add(scrollPane);
revalidate();
}
private void toggleVisible(){
if(visible){
setBackground(new Color(255, 255, 255, 1));
textArea.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
scrollPane.setOpaque(false);
textArea.setFont(new Font("굴림", Font.PLAIN, 20));
}
else{
setBackground(new Color(255, 255, 255, 255));
textArea.setOpaque(true);
scrollPane.getViewport().setOpaque(true);
scrollPane.setOpaque(true);
textArea.setFont(new Font("굴림", Font.PLAIN, 20));
}
repaint();
visible = !visible;
}
}
+)
There are runtime screenshot. "|" at second picture is a cursor which moved right as far as possible. and I don't understand why I can't move cursor to right more.
Something must be wrong... but I don't know what it is.
first
second
package newjframe;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.event.MouseInputAdapter;
public class NewJFrame extends javax.swing.JFrame {
public NewJFrame() {
initComponents();
setLocationRelativeTo(null);
}
public class Draggable extends JComponent {
private Point pointPressed;
private JComponent draggable;
public Draggable(final JComponent component, final int x, final int y) {
draggable = component;
setCursor(new Cursor(Cursor.HAND_CURSOR));
setLocation(x, y);
setSize(component.getPreferredSize());
setLayout(new BorderLayout());
add(component);
MouseInputAdapter mouseAdapter = new MouseHandler();
addMouseMotionListener(mouseAdapter);
addMouseListener(mouseAdapter);
}
public class MouseHandler extends MouseInputAdapter {
#Override
public void mouseDragged(final MouseEvent e) {
Point pointDragged = e.getPoint();
Point location = getLocation();
location.translate(pointDragged.x - pointPressed.x,
pointDragged.y - pointPressed.y);
setLocation(location);
}
#Override
public void mousePressed(final MouseEvent e) {
pointPressed = e.getPoint();
}
}
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
panel = new javax.swing.JPanel();
layer = new javax.swing.JLayeredPane();
cbb = new javax.swing.JComboBox<>();
label = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
cbb.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3"}));
cbb.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbbActionPerformed(evt);
}
});
layer.setLayer(cbb, javax.swing.JLayeredPane.DEFAULT_LAYER);
layer.setLayer(label, javax.swing.JLayeredPane.DEFAULT_LAYER);
javax.swing.GroupLayout layerLayout = new javax.swing.GroupLayout(layer);
layer.setLayout(layerLayout);
layerLayout.setHorizontalGroup(
layerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layerLayout.createSequentialGroup()
.addGap(41, 41, 41)
.addComponent(cbb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(129, 129, 129)
.addComponent(label)
.addContainerGap(202, Short.MAX_VALUE))
);
layerLayout.setVerticalGroup(
layerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layerLayout.createSequentialGroup()
.addGap(30, 30, 30)
.addGroup(layerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(label)
.addComponent(cbb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(329, Short.MAX_VALUE))
);
javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
panel.setLayout(panelLayout);
panelLayout.setHorizontalGroup(
panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(layer)
);
panelLayout.setVerticalGroup(
panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(layer)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
private void cbbActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
int[] xy = {100, 200, 300};
label.setText("DRAG THIS");
switch (cbb.getSelectedIndex()) {
case 0:
draglabel = new Draggable(label, xy[0], xy[0]);
layer.add(draglabel);
break;
case 1:
draglabel = new Draggable(label, xy[0], xy[1]);
layer.add(draglabel);
break;
case 2:
draglabel = new Draggable(label, xy[0], xy[2]);
layer.add(draglabel);
break;
default:
draglabel = new Draggable(label, xy[0], xy[0]);
layer.add(draglabel);
}
}
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JComboBox<String> cbb;
private javax.swing.JLabel label;
private javax.swing.JLayeredPane layer;
private javax.swing.JPanel panel;
// End of variables declaration
Draggable draglabel;
}
The above code should allow the Jlabels to be dragged and dropped with ease, but every time they're called with the actionlistener in JComboBox, they become harder to drag and drop. GIF added to for better clarity https://imgur.com/rPL5ZMC I have tried repaint() method in the class method, and actionlistner but it didn't work
Again, I would tend to simplify try to clarify things, including:
Use the much simpler MouseListener/MouseAdapter and not D&D as you initially were doing. You appear to have made this change.
Not wrapping the JLabel unnecessarily in another component
Thus the Mouse listeners would be added directly on the JLabel and not on a wrapper object.
Not changing the JLayeredPane's default and unique layout
Explicitly removing the old components before adding new ones
Calling repaint() on the JLayeredPane after adding or removing components.
For example, something like this:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class TestDragging extends JPanel {
private static final String[] ITEMS = {"Item One", "Item Two", "Item Three"};
private static final Dimension PREF_SIZE = new Dimension(400, 400);
private JLabel label;
private JComboBox<String> comboBox = new JComboBox<>(ITEMS);
private JLayeredPane layeredPane = new JLayeredPane();
public TestDragging() {
comboBox.addActionListener(new ComboListener());
JPanel topPanel = new JPanel();
topPanel.add(comboBox);
layeredPane.setPreferredSize(PREF_SIZE);
layeredPane.setBorder(BorderFactory.createEtchedBorder());
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(layeredPane, BorderLayout.CENTER);
}
private class ComboListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (label != null) {
layeredPane.remove(label);
}
int index = comboBox.getSelectedIndex();
int x = 100;
int y = 100 + 100 * index;
String text = comboBox.getSelectedItem().toString();
label = createDraggingLabel(x, y, text);
layeredPane.add(label, JLayeredPane.DEFAULT_LAYER);
layeredPane.repaint();
}
private JLabel createDraggingLabel(int x, int y, String text) {
JLabel label = new JLabel(text);
label.setSize(label.getPreferredSize());
label.setLocation(x, y);
MyMouse myMouse = new MyMouse();
label.addMouseListener(myMouse);
label.addMouseMotionListener(myMouse);
return label;
}
}
private static void createAndShowGui() {
TestDragging mainPanel = new TestDragging();
JFrame frame = new JFrame("Test Dragging");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MyMouse extends MouseAdapter {
private Point pointPressed = null;
#Override
public void mousePressed(MouseEvent e) {
pointPressed = e.getPoint();
}
#Override
public void mouseDragged(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
label.setCursor(new Cursor(Cursor.HAND_CURSOR));
Point pointDragged = e.getPoint();
Point location = label.getLocation();
int dx = pointDragged.x - pointPressed.x;
int dy = pointDragged.y - pointPressed.y;
location.translate(dx, dy);
label.setLocation(location);
Container container = label.getParent();
container.repaint();
}
}
I've called and instantiated the drag n drop function in the constructor then I've used label.setLocation(x, y) to solve this problem since the JComboBox merely determines the position of the labels, I do not need to have re-instantiate the object every time actionperformed is called.
I have a short toolbar at the left side of my application. When user points this toolbar, I open a semitransparent full toolbar (I use GlassPane to do it). All except semitransparency works fine.
Here is the screenshot of my example program:
As you see the first button is painted correctly, but all another have completly transparent background.
Here is my code (SSCCE):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.metal.MetalLookAndFeel;
/**
* <code>FlyOutExample</code>.
*/
public class FlyOutExample implements Runnable {
private static final String[] BUTTONS = {"First button", "Second", "Another button", "Last Button", "End"};
private static final Color HT_BLUE = new Color(0, 0, 255, 160); // half transparent blue
private JPanel shortPanel = new JPanel(new GridLayout(5, 1));
private JPanel fullPanel = new JPanel(new GridLayout(5, 1));
private JPanel fullPanelWrapper = new JPanel(new BorderLayout());
private JPanel shortPanelWrapper = new JPanel(new BorderLayout());
private JFrame frm;
public static void main(String[] args) {
SwingUtilities.invokeLater(new FlyOutExample());
}
#Override
public void run() {
try {
UIManager.setLookAndFeel(MetalLookAndFeel.class.getName());
} catch (Exception e) {
e.printStackTrace();
}
for (String s : BUTTONS) {
JButton b = new JButton(s.substring(0, 1));
b.setBackground(Color.BLUE);
b.setForeground(Color.RED);
b.setUI(new BasicButtonUI());
shortPanel.add(b);
b = new JButton(s);
b.setForeground(Color.RED);
b.setOpaque(false);
b.setHorizontalAlignment(SwingConstants.LEADING);
b.setBackground(HT_BLUE);
b.setUI(new BasicButtonUI() {
#Override
public void update(Graphics g, JComponent c) {
Color old = g.getColor();
g.setColor(HT_BLUE);
g.fillRect(0, 0, c.getWidth(), c.getHeight());
g.setColor(old);
paint(g, c);
}
});
fullPanel.add(b);
}
frm = new JFrame("Flyout example");
shortPanelWrapper.setOpaque(false);
shortPanelWrapper.add(shortPanel, BorderLayout.NORTH);
JPanel bluePanel1 = new JPanel();
bluePanel1.setOpaque(true);
bluePanel1.setBackground(Color.BLUE);
shortPanelWrapper.add(bluePanel1);
fullPanel.setOpaque(false);
fullPanelWrapper.setOpaque(false);
fullPanelWrapper.add(fullPanel, BorderLayout.NORTH);
JPanel bluePanel2 = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
Color old = g.getColor();
g.setColor(HT_BLUE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(old);
}
};
bluePanel2.setOpaque(false);
fullPanelWrapper.add(bluePanel2);
MouseListener openListener = new OpenSideBarListener();
for (Component c : shortPanel.getComponents()) {
c.addMouseListener(openListener);
}
bluePanel1.addMouseListener(openListener);
MouseListener closeListener = new CloseSideBarListener();
for (Component c : fullPanel.getComponents()) {
c.addMouseListener(closeListener);
}
bluePanel2.addMouseListener(closeListener);
JPanel topPanel = new JPanel();
topPanel.setBackground(Color.GREEN);
topPanel.setPreferredSize(new Dimension(0, 30));
JPanel bottomPanel = new JPanel();
bottomPanel.setBackground(Color.GREEN);
bottomPanel.setPreferredSize(new Dimension(0, 30));
frm.add(topPanel, BorderLayout.NORTH);
frm.add(bottomPanel, BorderLayout.SOUTH);
frm.add(shortPanelWrapper, BorderLayout.WEST);
frm.add(new JScrollPane(new JTable(40, 7)));
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private void openPopup() {
if (shortPanelWrapper.getMousePosition() != null) {
Container glassPane = (Container) frm.getGlassPane();
glassPane.setLayout(null);
fullPanelWrapper.setLocation(shortPanelWrapper.getLocation());
fullPanelWrapper.setSize(140, shortPanelWrapper.getHeight());
glassPane.add(fullPanelWrapper);
glassPane.setVisible(true);
}
}
private void closePopup() {
if (fullPanelWrapper.getMousePosition() == null) {
Container glassPane = (Container) frm.getGlassPane();
glassPane.removeAll();
glassPane.setVisible(false);
}
}
private class OpenSideBarListener extends MouseAdapter {
#Override
public void mouseEntered(MouseEvent e) {
openPopup();
}
}
private class CloseSideBarListener extends MouseAdapter {
#Override
public void mouseExited(MouseEvent e) {
closePopup();
}
}
}
My JDK is: 1.8_91, OS: Windows 7
My question is: what should I do to paint all my buttons correct?
P.S. In real application I have a custom UI for all buttons present in the left toolbar, so please don't remove the UI for my buttons.
UPDATE
I've started the app again (without any changes) and got another bug
Here ist the new picture:
Probably it's a bug of my graphic card?
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.
I want to draw a line in a JPanel.
This is my GUI and I want a line in the JPanel in white.
I find many examples but the problem is the how to use it.
In many exmples, always they draw in a JFrame that extends from a JPanel.
I want to add the Panel to the Frame and add some buttons to draw lines in many directions and use the X button in center to clean the JPanel.
This is the code of the interface:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class circuit extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
circuit frame = new circuit();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public circuit() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 559, 332);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 21, 359, 255);
contentPane.add(scrollPane);
JPanel panel = new JPanel();
scrollPane.setViewportView(panel);
panel.setBackground(Color.WHITE);
JLabel label = new JLabel("New label");
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
/////////////
}
});
label.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\up.png"));
label.setBounds(447, 66, 46, 48);
contentPane.add(label);
JLabel label_1 = new JLabel("New label");
label_1.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\down.png"));
label_1.setBounds(447, 159, 46, 48);
contentPane.add(label_1);
JLabel label_2 = new JLabel("New label");
label_2.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\right.png"));
label_2.setBounds(495, 112, 46, 48);
contentPane.add(label_2);
JLabel label_3 = new JLabel("New label");
label_3.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\left.png"));
label_3.setBounds(398, 112, 46, 48);
contentPane.add(label_3);
JLabel label_4 = new JLabel("New label");
label_4.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\1303860240_list-remove.png"));
label_4.setBounds(447, 112, 46, 48);
contentPane.add(label_4);
}
}
This is the code to draw a line
public void paint(Graphics graphics)
{
graphics.drawLine(10, 20, 300, 310);
}
So how to use this lines ....
Thanks in advance.
Best regards,
Ali
It may be easier to draw lines using the following approach:
click to mark the first endpoint
drag to show the line in progress
release to mark the second endpoint
This related example may offer some additional guidance.
Addendum
The example below implements the outline above.
I've update the example to show how to use a panel of buttons to affect the drawing.
See also this related example that uses the Action interface with key bindings.
I've updated this example to use Key Bindings.
LinePanel.java
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
* #see https://stackoverflow.com/questions/6991648
* #see https://stackoverflow.com/questions/6887296
* #see https://stackoverflow.com/questions/5797965
*/
public class LinePanel extends JPanel {
private MouseHandler mouseHandler = new MouseHandler();
private Point p1 = new Point(100, 100);
private Point p2 = new Point(540, 380);
private boolean drawing;
public LinePanel() {
this.setPreferredSize(new Dimension(640, 480));
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(8,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
drawing = true;
p1 = e.getPoint();
p2 = p1;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
drawing = false;
p2 = e.getPoint();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
if (drawing) {
p2 = e.getPoint();
repaint();
}
}
}
private class ControlPanel extends JPanel {
private static final int DELTA = 10;
public ControlPanel() {
this.add(new MoveButton("\u2190", KeyEvent.VK_LEFT, -DELTA, 0));
this.add(new MoveButton("\u2191", KeyEvent.VK_UP, 0, -DELTA));
this.add(new MoveButton("\u2192", KeyEvent.VK_RIGHT, DELTA, 0));
this.add(new MoveButton("\u2193", KeyEvent.VK_DOWN, 0, DELTA));
}
private class MoveButton extends JButton {
KeyStroke k;
int dx, dy;
public MoveButton(String name, int code,
final int dx, final int dy) {
super(name);
this.k = KeyStroke.getKeyStroke(code, 0);
this.dx = dx;
this.dy = dy;
this.setAction(new AbstractAction(this.getText()) {
#Override
public void actionPerformed(ActionEvent e) {
LinePanel.this.p1.translate(dx, dy);
LinePanel.this.p2.translate(dx, dy);
LinePanel.this.repaint();
}
});
ControlPanel.this.getInputMap(WHEN_IN_FOCUSED_WINDOW)
.put(k, k.toString());
ControlPanel.this.getActionMap()
.put(k.toString(), new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
MoveButton.this.doClick();
}
});
}
}
}
private void display() {
JFrame f = new JFrame("LinePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.add(new ControlPanel(), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new LinePanel().display();
}
});
}
}
Is this going to work like an etch-a-sketch? Then you need to track the current position of the point.
Point current = new Point(0, 0); //for example.
Then when the user clicks the buttons you can simply increment or decrement x and y accordingly.
On left arrow:
current.setX(current.getX() - INC);
where INC could be a variable that specifies the length of the distance to draw the line. Maybe 5? Always set a second point p1 to the previous location though.
It is always easier to create a class that extends Canvas or JPanel to draw on rather than draweing directly on the JFrame.
e.g.
public class Circuit extends JFrame {
Point p1, current;
JPanel drawPanel;
//your other declarations
public Circuit(){
super();
drawPanel = new DrawPanel();
p1 = new Point(0, 0);
current = new Point(0, 0);
add(drawPanel, BorderLayout.CENTER);
//your other code
}
class DrawingPanel extends JPanel{
public void paintComponent(Graphics g){
g.drawLine(p1.getX(), p1.getY(), current.getX(), current.getY());
}
}
//the rest of your code.
}
There is a simple answer for triggering graphics: e.g. The following code can be placed inside a click event and used for drawing a few simple objects on a jPanel. jPanel1 in this case was situated on one side of a tabbed jPanel7 and next to the triggering button. To do this in netbeans GUI, the code was placed inside the button action event. Once the usual errors appeared for not having the proper imports, right click on the code and click on "fix imports". Bingo, all is well :-) Warning: the setBackground command for the panel will override the graphics object. If you set the background color without using the graphics object, you will not see your objects!
Graphics g = jPanel1.getGraphics();
g.setColor(Color.blue);
g.drawLine( 0, 50, 20, 50);
g.setColor(Color.white);
g.fillRect(40, 50, 20, 20);
g.setColor(Color.blue);
g.drawRect(40, 50, 20, 20);
g.drawOval(80, 50, 20, 20);
g.setColor(Color.green);
g.fillOval(80, 50, 18, 18);
This restores your faith in true love :-)
The difficulty here is that any change or repaint will erase your effort. This approach is specifically discouraged by the Java founders. But in the current rendition of Netbeans Swing, where extending the jPanel is made difficult by locking code changes, this approach could be your only short term solution. A simple persistent graphic extension for the jPanel would be a most welcome addition to the current Netbeans Swing environment, a graphics panel. This would allow you to drag and drop the graphics panel and then get on with the event driven use of that panel. 40 other IDE's already have this, it seems Java has been slow to add this feature.