I am trying to create a 2d grid on a JPanel with Zoom functionality. The user will draw on the grid then if desired zoom in and out. Image of Grid
When I currently zoom in there is a screen shake like issue/bug when I move the mouse around, which I would like to remove.
The mouse wheel is used to zoom in and out.
Grid to be drawn at certain scale factor:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class DrawExample extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private double zoom = 1d;
private int tranx;
private int trany;
DrawPanel drawPanel;
int snapmousepositionx, snapmousepositiony;//current snap coords
int currentmousepositionx,currentmousepositiony;
public DrawExample() {
drawPanel = new DrawPanel();
JPanel containerPanel = new JPanel();
JFrame frame = new JFrame(); // Instance of a JFrame
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(800, 800);
//drawPanel.setSize(800, 800);
containerPanel.setLayout(new GridBagLayout());
containerPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(1, 0, 1)));
containerPanel.add(drawPanel);
frame.add(new JScrollPane(containerPanel));
drawPanel.addMouseWheelListener(new MouseAdapter() { //add wheel listener to drawPanel
#Override
public void mouseWheelMoved(MouseWheelEvent e) { //when wheel is moved
if (e.getPreciseWheelRotation() < 0) {
zoom += 0.1;
} else {
zoom -= 0.1;
}
if (zoom < 0.01) {
zoom = 0.01;
}
drawPanel.repaint();
}
});
drawPanel.addMouseMotionListener(new MouseAdapter() {
public void mouseMoved(MouseEvent me) {
super.mouseMoved(me);
drawPanel.createSnapGrid(me.getPoint().x, me.getPoint().y);
tranx=me.getPoint().x;
trany=me.getPoint().y;
drawPanel.repaint();
}
});
frame.setVisible(true);
}
public class DrawPanel extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 800);
}
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
zoom=Math.round(zoom*10.0)/10.0;
AffineTransform at = g2d.getTransform();
at.translate(tranx, trany);
at.scale(zoom, zoom);
at.translate(-tranx, -trany);
g2d.setTransform(at);
g2d.setColor(Color.lightGray);
drawGrid(g2d);
}
public void createSnapGrid(int x, int y) {
currentmousepositionx = x;
currentmousepositiony = y;
int remainderx = currentmousepositionx % 10, remaindery = currentmousepositiony % 10;
if (remainderx<800/2) setSnapX(currentmousepositionx - remainderx) ;
else setSnapX(currentmousepositionx + (10-remainderx));
if (remaindery<800/2) setSnapY(currentmousepositiony - remaindery);
else setSnapY(currentmousepositiony + (10)-remaindery);
}
}
public void drawGrid(Graphics2D g) {
g.setColor(Color.lightGray);
g.clearRect(0, 0, 800, 800);
System.out.println(getHeight());
//grid vertical lines
for (int i= (10);i<800;i+=10) {
g.drawLine(i, 0, i, 800);
}
//grid horizontal lines
for (int j= (10);j<800;j+=10) {
g.drawLine(0, j, 800, j);
}
//show the snapped point
g.setColor(Color.BLACK);
if ( getSnapX()>=0 && getSnapY()>=0 && getSnapX()<=800 && getSnapY()<=800) {
// result =true;
g.drawOval((int) ( getSnapX())-4, (int) (getSnapY()-4), 8, 8);
}
}
public int getSnapX(){
return (this.snapmousepositionx);
}
public int getSnapY(){
return (this.snapmousepositiony);
}
public void setSnapX(int snap){
this.snapmousepositionx=(int) (snap);
}
public void setSnapY(int snap){
this.snapmousepositiony=(int) (snap);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new DrawExample();
}
});
}
}
I am having trouble drawing on a translucent frame. When the "alphaValue" is 255 everything works as expected. But I need a translucent frame. I created a small test class below that demonstrates the problem. As you can see the "MIDDLE" rectangle appears all the time. But the "DRAW" rectangle only appears when "alphaValue" is 255. When it is <=254 you can see via print lines that the method is still called, but the image does not appear to refresh. Thank you in advance for any help.
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class TransparencyTest {
private static Point startPoint = new Point();
private static Point endPoint = new Point();
public static void main(String[] args) {
new TransparencyTest().test();
}
#SuppressWarnings("serial")
private void test() {
int alphaValue = 255;
Frame myFrame = new Frame();
myFrame.setUndecorated(true);
myFrame.setBackground(new Color(0, 0, 0, alphaValue));
myFrame.setSize(800, 800);
Panel myPanel = new Panel() {
public void paint(Graphics g) {
super.paint(g);
System.out.println("PAINT");
g.setColor(new Color(255, 0, 0, 255));
if(startPoint.equals(new Point())) {
System.out.println("MIDDLE");
g.drawRect(200, 200, 400, 400);
}
else {
System.out.println("DRAW");
g.drawRect(
(int)Math.min(startPoint.getX(), endPoint.getX()),
(int)Math.min(startPoint.getY(), endPoint.getY()),
(int)Math.abs(startPoint.getX() - endPoint.getX()),
(int)Math.abs(startPoint.getY() - endPoint.getY())
);
}
}
};
myFrame.add(myPanel);
MouseAdapter myMouseAdapter = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
}
public void mouseDragged(MouseEvent e) {
endPoint = e.getPoint();
myPanel.repaint();
}
};
myPanel.addMouseListener(myMouseAdapter);
myPanel.addMouseMotionListener(myMouseAdapter);
myFrame.setVisible(true);
}
}
AWT components don't have a concept of transparency in of themselves, they are always opaque.
You have use a JPanel, which you use setOpaque to control the opacity (on or off) with. This will allow the panel to become see through and you should then be able to see the alpha affect applied directly to the frame...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransparencyTest {
private static Point startPoint = new Point();
private static Point endPoint = new Point();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
new TransparencyTest().test();
}
});
}
#SuppressWarnings("serial")
private void test() {
int alphaValue = 128;
JFrame myFrame = new JFrame();
myFrame.setUndecorated(true);
myFrame.setBackground(new Color(0, 0, 0, alphaValue));
// myFrame.setOpacity(0.1f);
myFrame.setSize(800, 800);
myFrame.setLocation(100, 100);
JPanel myPanel = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("PAINT");
g.setColor(new Color(255, 0, 0, 255));
if (startPoint.equals(new Point())) {
System.out.println("MIDDLE");
g.drawRect(200, 200, 400, 400);
} else {
System.out.println("DRAW");
g.drawRect(
(int) Math.min(startPoint.getX(), endPoint.getX()),
(int) Math.min(startPoint.getY(), endPoint.getY()),
(int) Math.abs(startPoint.getX() - endPoint.getX()),
(int) Math.abs(startPoint.getY() - endPoint.getY())
);
}
}
};
myPanel.setOpaque(false);
myFrame.add(myPanel);
MouseAdapter myMouseAdapter = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
}
public void mouseDragged(MouseEvent e) {
endPoint = e.getPoint();
myPanel.repaint();
}
};
myPanel.addMouseListener(myMouseAdapter);
myPanel.addMouseMotionListener(myMouseAdapter);
myFrame.setVisible(true);
}
}
I am using a JSeparator in my java swing application. The normal implementation makes the separator normal line; but what I need is the separator should be dashed(like we create dashed border). Is there any way we can do that?
Thanks
To create a custom JSeparator, you can override the paint() method of BasicSeparatorUI, discussed here, and draw the line using a dashed Stroke, illustrated here.
Addendum: A more familiar approach overrides paintComponent(), as shown in the accepted answer and encapsulated conveniently in this StrokedSeparator. The variation below replaces drawLine() with draw() using a Line2D, which takes advantage of the stroke's geometry.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import static javax.swing.JSeparator.*;
/**
* #see https://stackoverflow.com/a/74657060/230513
*/
public class StrokeSepTest {
private static final int N = 10;
private void display() {
var f = new JFrame("StrokeSepTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
var stroke = new BasicStroke(8.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, new float[]{5.0f}, 0.0f);
var panel = new JPanel(new GridLayout(0, 1)) {
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
};
panel.setBackground(Color.white);
for (int i = 0; i < N; i++) {
Color color = Color.getHSBColor((float) i / N, 1, 1);
panel.add(new StrokedSeparator(stroke, HORIZONTAL, color));
}
f.add(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
// #see https://stackoverflow.com/a/74657060/230513 */
private static class StrokedSeparator extends JSeparator {
private Stroke stroke;
public StrokedSeparator() {
this(new BasicStroke(1F), HORIZONTAL);
}
public StrokedSeparator(int orientation) {
this(new BasicStroke(1F), orientation);
}
public StrokedSeparator(Stroke stroke) {
this(stroke, HORIZONTAL);
}
public StrokedSeparator(Stroke stroke, int orientation) {
super(orientation);
this.stroke = stroke;
}
public StrokedSeparator(Stroke stroke, int orientation, Color color) {
super(orientation);
super.setForeground(color);
this.stroke = stroke;
}
#Override
public void paintComponent(Graphics g) {
var graphics = (Graphics2D) g;
var s = getSize();
graphics.setStroke(stroke);
graphics.setColor(getForeground());
if (getOrientation() == JSeparator.VERTICAL) {
graphics.draw(new Line2D.Double(0, 0, 0, s.height));
} else // HORIZONTAL
{
graphics.draw(new Line2D.Double(0, 0, s.width, 0));
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new StrokeSepTest()::display);
}
}
You can use the following code snippet to create a dashed line.
import java.awt.Container;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSeparator;
public class SeparatorSample {
public static void main(String args[]) {
JFrame f = new JFrame("JSeparator Sample");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = f.getContentPane();
content.setLayout(new GridLayout(0, 1));
JLabel above = new JLabel("Above Separator");
content.add(above);
JSeparator separator = new JSeparator() {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
for (int x = 0; x < 300; x += 15)
g.drawLine(x, 0, x + 10, 0);
}
};
content.add(separator);
JLabel below = new JLabel("Below Separator");
content.add(below);
f.setSize(300, 100);
f.setVisible(true);
}
}
With a slight modification to trashgod's answer, I found that using paintComponent() rather than paint() works very well for me:
Stroke stroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 5.0f },
0.0f);
JSeparator separator = new StrokedSeparator(stroke);
// Add separator to container
And here's the StrokedSeparator class:
import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import javax.swing.JSeparator;
public class StrokedSeparator extends JSeparator {
private static final long serialVersionUID = 1L;
private Stroke stroke;
public StrokedSeparator() {
this(new BasicStroke(1F), HORIZONTAL);
}
public StrokedSeparator(int orientation) {
this(new BasicStroke(1F), orientation);
}
public StrokedSeparator(Stroke stroke) {
this(stroke, HORIZONTAL);
}
public StrokedSeparator(Stroke stroke, int orientation) {
super(orientation);
this.stroke = stroke;
}
#Override
public void paintComponent(Graphics g) {
Dimension s = getSize();
Graphics2D graphics = (Graphics2D) g;
graphics.setStroke(stroke);
if (getOrientation() == JSeparator.VERTICAL) {
graphics.setColor(getForeground());
graphics.drawLine(0, 0, 0, s.height);
graphics.setColor(getBackground());
graphics.drawLine(1, 0, 1, s.height);
} else // HORIZONTAL
{
graphics.setColor(getForeground());
graphics.drawLine(0, 0, s.width, 0);
graphics.setColor(getBackground());
graphics.drawLine(0, 1, s.width, 1);
}
}
}
I want to make a round rectangle JTextField. I write a sub class of AbstractBorder to realize it.But I run into some problems.
My requirement is:
What I get is:
My code is :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.AbstractBorder;
import javax.swing.border.EmptyBorder;
public class JTextFieldTest {
JTextField textField;
boolean activate = false;
public void createUI(){
JFrame frame = new JFrame("Test JTextField");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
MainPanel mainPanel = new MainPanel();
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
JTextFieldTest jTextFieldTest = new JTextFieldTest();
jTextFieldTest.createUI();
}
#SuppressWarnings("serial")
class MainPanel extends JPanel{
public MainPanel(){
textField = new JTextField("Please input:");
Font fieldFont = new Font("Arial", Font.PLAIN, 20);
textField.setFont(fieldFont);
textField.setBackground(Color.white);
textField.setForeground(Color.gray.brighter());
textField.setColumns(30);
textField.setBorder(BorderFactory.createCompoundBorder(new CustomeBorder(),
new EmptyBorder(new Insets(10, 20, 10, 20))));
textField.addActionListener(new FieldListener());
textField.addMouseListener(new FieldMouseListener());
add(textField,BorderLayout.CENTER);
setBackground(Color.blue);
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
}
#SuppressWarnings("serial")
class CustomeBorder extends AbstractBorder{
#Override
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
// TODO Auto-generated method stub
super.paintBorder(c, g, x, y, width, height);
g.setColor(Color.black);
g.drawRoundRect(x, y, width, height, 20, 20);
}
}
class FieldListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println(textField.getText());
}
}
class FieldMouseListener implements MouseListener{
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(activate == false){
textField.setText("");
}
activate = true;
textField.setForeground(Color.black);
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
I can get another effect by using
textField.setOpaque(false);
g.setColor(Color.white);
g.drawRoundRect(x, y, width - 1, height - 1, 20, 20);
Another effect is:
In sum, what can I do to realize my requirement?
#Arijit, it's the effect of your solution when it runs on my computer.
Use a TextBubbleBorder.
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
class TextBubbleBorder extends AbstractBorder {
private Color color;
private int thickness = 4;
private int radii = 8;
private int pointerSize = 7;
private Insets insets = null;
private BasicStroke stroke = null;
private int strokePad;
private int pointerPad = 4;
RenderingHints hints;
TextBubbleBorder(
Color color) {
this(color, 4, 8, 7);
}
TextBubbleBorder(
Color color, int thickness, int radii, int pointerSize) {
this.thickness = thickness;
this.radii = radii;
this.pointerSize = pointerSize;
this.color = color;
stroke = new BasicStroke(thickness);
strokePad = thickness/2;
hints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int pad = radii + strokePad;
int bottomPad = pad + pointerSize + strokePad;
insets = new Insets(pad,pad,bottomPad,pad);
}
#Override
public Insets getBorderInsets(Component c) {
return insets;
}
#Override
public Insets getBorderInsets(Component c, Insets insets) {
return getBorderInsets(c);
}
#Override
public void paintBorder(
Component c,
Graphics g,
int x, int y,
int width, int height) {
Graphics2D g2 = (Graphics2D)g;
int bottomLineY = height-thickness-pointerSize;
RoundRectangle2D.Double bubble = new RoundRectangle2D.Double(
0+strokePad,
0+strokePad,
width-thickness,
bottomLineY,
radii,
radii
);
Polygon pointer = new Polygon();
// left point
pointer.addPoint(
strokePad+radii+pointerPad,
bottomLineY);
// right point
pointer.addPoint(
strokePad+radii+pointerPad+pointerSize,
bottomLineY);
// bottom point
pointer.addPoint(
strokePad+radii+pointerPad+(pointerSize/2),
height-strokePad);
Area area = new Area(bubble);
area.add(new Area(pointer));
g2.setRenderingHints(hints);
Area spareSpace = new Area(new Rectangle(0,0,width,height));
spareSpace.subtract(area);
g2.setClip(spareSpace);
g2.clearRect(0,0,width,height);
g2.setClip(null);
g2.setColor(color);
g2.setStroke(stroke);
g2.draw(area);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JTextField o = new JTextField(
"The quick brown fox jumps over the lazy dog!");
o.setBorder(new TextBubbleBorder(Color.MAGENTA.darker(),2,4,0));
JOptionPane.showMessageDialog(null, o);
}
});
}
}
I have a solution and I don't need to use
textField.setOpaque(false);
I just use the following code to fill the space.
#SuppressWarnings("serial")
class CustomeBorder extends AbstractBorder{
#Override
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
// TODO Auto-generated method stubs
super.paintBorder(c, g, x, y, width, height);
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(10));
g2d.setColor(new Color(68,184,224));
g2d.drawRoundRect(x, y, width - 1, height - 1, 20, 20);
}
}
You should adjust the width of BasicStroke based on your JTextField.
The final result is:
Use this:
JTextField Mytxtfield = new JTextField()
{protected void paintComponent( Graphics g )
{
if ( !isOpaque( ) )
{
super.paintComponent( g );
return;
}
Graphics2D g2d = (Graphics2D)g;
GradientPaint gp = new GradientPaint(
0, 0, color1,
0, 20, color2);
g2d.setPaint( gp );
// g2d.fillRect( 0, 0, w, h );
g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 10, 10);
setOpaque( false );
super.paintComponent( g );
setOpaque( true );
}};
Full Working code:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Shape;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
public class DBconnection extends JFrame {
private JPanel contentPane;
private JTextField textFieldHost;
private Color color2 = Color.white;
private Color color1 = Color.white;
public DBconnection() throws SAXException, IOException, ParserConfigurationException {
setTitle("Connect To MDM Database");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(450, 200, 410, 280);
contentPane = new JPanel();
contentPane.setBackground(SystemColor.inactiveCaption);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[]{0, 0, 0, 0};
gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 1.0, Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
textFieldHost = new JTextField()
{protected void paintComponent( Graphics g )
{
if ( !isOpaque( ) )
{
super.paintComponent( g );
return;
}
Graphics2D g2d = (Graphics2D)g;
GradientPaint gp = new GradientPaint(
0, 0, color1,
0, 20, color2);
g2d.setPaint( gp );
// g2d.fillRect( 0, 0, w, h );
g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 10, 10);
setOpaque( false );
super.paintComponent( g );
setOpaque( true );
}};
GridBagConstraints gbc_textFieldHost = new GridBagConstraints();
gbc_textFieldHost.insets = new Insets(20, 40, 5, 0);
gbc_textFieldHost.fill = GridBagConstraints.HORIZONTAL;
gbc_textFieldHost.gridwidth=3;
gbc_textFieldHost.gridx = 2;
gbc_textFieldHost.gridy = 4;
gbc_textFieldHost.ipady=5;
contentPane.add(textFieldHost, gbc_textFieldHost);
textFieldHost.setBorder(javax.swing.BorderFactory.createEmptyBorder(2, 2,2,2));
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DBconnection frame = new DBconnection();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
Also by changing the value of color1 and color2, you can get a gradient effect.
I have modified your code and get this:
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.AbstractBorder;
public class JTextFieldTest {
JTextField textField;
boolean activate = false;
public void createUI(){
JFrame frame = new JFrame("Test JTextField");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
MainPanel mainPanel = new MainPanel();
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
JTextFieldTest jTextFieldTest = new JTextFieldTest();
jTextFieldTest.createUI();
}
#SuppressWarnings("serial")
class MainPanel extends JPanel{
public MainPanel(){
textField = new JTextField("Test JTextField")
{protected void paintComponent( Graphics g )
{
if ( !isOpaque( ) )
{
super.paintComponent( g );
return;
}
Graphics2D g2d = (Graphics2D)g;
GradientPaint gp = new GradientPaint(
0, 0, Color.white,
0, 20, Color.white);
g2d.setPaint( gp );
// g2d.fillRect( 0, 0, w, h );
g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);
setOpaque( false );
super.paintComponent( g );
setOpaque( true );
}};
textField.setBorder(BorderFactory.createEmptyBorder());
Font fieldFont = new Font("Arial", Font.PLAIN, 20);
textField.setFont(fieldFont);
textField.setColumns(30);
textField.addActionListener(new FieldListener());
textField.addMouseListener(new FieldMouseListener());
add(textField,BorderLayout.CENTER);
setBackground(Color.blue);
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
}
class FieldListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println(textField.getText());
}
}
class FieldMouseListener implements MouseListener{
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
if(activate == false){
textField.setText("");
}
activate = true;
textField.setForeground(Color.black);
}
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
I want create a program that draw line on desktop with this property that user can click on desktop icons near the line.
I create sample. I create transparent frame and draw jWindow on this. in MouseReleased event dispose main frame then stay all jwindows that created. My code create many number of jwindow and this is very bad. For draw line 30cm program create over than 400 jwindow and this causes os be very heavy.
Can help me anybody?
(Excuse me for my ugly english)
package PKHMain;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;
public class FRMMain extends JFrame implements MouseListener, MouseMotionListener {
public FRMMain() {
this.setUndecorated(true);
this.setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setLayout(null);
this.setBackground(new Color(0, 0, 0, 0));
this.setVisible(true);
addMouseListener(this);
addMouseMotionListener(this);
}
public static void main(String[] args) {
new FRMMain();
}
#Override
public void mousePressed(MouseEvent event) {
}
#Override
public void paint(Graphics g) {
repaint();
}
#Override
public void mouseClicked(MouseEvent event) {
}
#Override
public void mouseEntered(MouseEvent event) {
}
#Override
public void mouseExited(MouseEvent event) {
}
#Override
public void mouseReleased(MouseEvent event) {
this.dispose();
}
#Override
public void mouseDragged(MouseEvent event) {
int x = event.getX();
int y = event.getY();
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
frame.setContentPane(new ShapedPane(x, y));
frame.pack();
frame.setLocation(x, y);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
public void mouseMoved(MouseEvent event) {
}
public class ShapedPane extends JPanel {
public int x1;
public int y1;
public ShapedPane(int x, int y) {
setOpaque(false);
setLayout(new GridBagLayout());
x1 = x;
y1 = y;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(5, 5);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(hints);
g2.setColor(Color.red);
g2.fill(new Ellipse2D.Double(0, 0, getWidth(), getHeight()));
g2.dispose();
}
}
}
You are touching system specific behavior with your program, e.g. on my machine the program will not receive any mouse event at all as the background color has an alpha value of zero. Setting it to at least one makes it receiving clicks and drags. So this is a way to control the desired click-through behavior but it might be the case that it doesn’t work for you.
Here is the program as it work on my machine (Java 7 and Windows 7):
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class FRMMain extends JFrame {
private final List<Shape> list=new ArrayList<>();
private boolean paintPhase=true;
public FRMMain() {
this.setUndecorated(true);
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(screenSize.width, screenSize.height);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setBackground(new Color(0, 0, 0, 1));
this.setOpacity(1f);
this.setAlwaysOnTop(true);
this.setVisible(true);
enableEvents(AWTEvent.MOUSE_EVENT_MASK|AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
#Override
protected void processMouseEvent(MouseEvent e) {
if(paintPhase && e.getID()==MouseEvent.MOUSE_RELEASED) {
paintPhase = false;
// on my machine the following line is enough to enable click-through
setBackground(new Color(0, 0, 0, 0));
// but if this doesn’t work, the following should do:
Area area=new Area();
BasicStroke b=new BasicStroke(2f);
for(Shape s:list) area.add(new Area(b.createStrokedShape(s)));
setShape(area);
}
super.processMouseEvent(e);
}
#Override
protected void processMouseMotionEvent(MouseEvent event)
{
if(paintPhase && event.getID()==MouseEvent.MOUSE_DRAGGED) {
int x = event.getX();
int y = event.getY();
list.add(new Ellipse2D.Float(x, y, 8, 8));
repaint();
}
super.processMouseMotionEvent(event);
}
#Override
public boolean contains(int x, int y) {
return paintPhase;
}
public static void main(String[] args) {
new FRMMain();
}
#Override
public void paint(Graphics g) {
Graphics2D gfx=(Graphics2D)g;
gfx.setColor(Color.RED);
for(Shape s:list) gfx.draw(s);
}
}