I'm doing a program involving the Pythagorean theorem, and wanted to leave a triangle in the middle, with three JTextField around three sides of it. I did it, but the problem is that when I create the JTextField and add it to the desired container, it is immense. It is a very large white rectangle that when I click to enter, get a small letter. So, my question is: How can I change the size of this JTextField to decrease it and avoid unnecessary sizes?
P.S:.'m Using Swing and AWT library for free!
Example of code:
Container content = window.getContentPane();
Contaiiner grid = new JPanel();
grid.setLayout(new GridLayout(3,3));
grid.add(new JTextField());
Well, this simple code, gives to you one example of the JTextField, when i executes than (with main method and more...) the JTextField is very very big, so, i want to decrease it.
Admittedly, it involves some guesses about your intention, but here is an example of what I think that you want to achieve:
It's a program that contains a panel with some points, and between each pair of points, it places a text field. The text fields are arranged so that their upper left corner remains at the center of the respective edge. When the points are dragged with the mouse, the locations of the text fields are updated accordingly. (In this example, the text fields contain the distance between the points - that is, the edge lengths - but this is just for illustration).
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TriangleTextFieldsTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new TriangleTextFieldsTest();
}
});
}
public TriangleTextFieldsTest()
{
JFrame frame = new JFrame();
frame.getContentPane().add(new TriangleTextFieldsPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class TriangleTextFieldsPanel extends JPanel
implements MouseListener, MouseMotionListener
{
private final List<Point2D> points;
private final List<JTextField> textFields;
private Point2D draggedPoint = null;
TriangleTextFieldsPanel()
{
super(null);
points = new ArrayList<Point2D>();
points.add(new Point2D.Double(250,250));
points.add(new Point2D.Double(750,250));
points.add(new Point2D.Double(500,500));
textFields = new ArrayList<JTextField>();
for (int i=0; i<points.size(); i++)
{
JTextField t = new JTextField(10);
textFields.add(t);
add(t);
}
updateTextFieldPositions();
updateTextFieldContents();
addMouseListener(this);
addMouseMotionListener(this);
}
private void updateTextFieldPositions()
{
for (int i=0; i<points.size(); i++)
{
Point2D p0 = points.get(i);
Point2D p1 = points.get((i+1)%points.size());
JTextField textField = textFields.get(i);
int cx = (int)(0.5 * (p1.getX() + p0.getX()));
int cy = (int)(0.5 * (p1.getY() + p0.getY()));
Dimension d = textField.getPreferredSize();
textField.setBounds(cx, cy, d.width, d.height);
}
}
private void updateTextFieldContents()
{
for (int i=0; i<points.size(); i++)
{
Point2D p0 = points.get(i);
Point2D p1 = points.get((i+1)%points.size());
JTextField textField = textFields.get(i);
double d = p0.distance(p1);
textField.setText(String.format("%.2f", d));
}
}
#Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLUE);
drawPoints(g, points);
g.setColor(Color.BLACK);
for (int i=0; i<points.size(); i++)
{
Point2D p0 = points.get(i);
Point2D p1 = points.get((i+1)%points.size());
g.draw(new Line2D.Double(p0,p1));
}
}
static void drawPoints(Graphics2D g, List<Point2D> points)
{
double r = 3;
for (Point2D point : points)
{
double x = point.getX();
double y = point.getY();
g.fill(new Ellipse2D.Double(
x-r, y-r, r+r, r+r));
}
}
#Override
public void mouseDragged(MouseEvent e)
{
if (draggedPoint != null)
{
draggedPoint.setLocation(e.getPoint());
updateTextFieldPositions();
updateTextFieldContents();
repaint();
}
}
#Override
public void mouseMoved(MouseEvent e)
{
}
#Override
public void mouseClicked(MouseEvent e)
{
}
#Override
public void mousePressed(MouseEvent e)
{
draggedPoint = null;
double thresholdSquared = 10*10;
double minDs = Double.MAX_VALUE;
for (Point2D point : points)
{
double ds = point.distanceSq(e.getPoint());
if (ds < thresholdSquared && ds < minDs)
{
minDs = ds;
draggedPoint = point;
}
}
}
#Override
public void mouseReleased(MouseEvent e)
{
draggedPoint = null;
}
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
}
Related
newbie programmer here.
I'm making a program that renders user-inputted equations in a Cartesian coordinate system. At the moment I'm having some issues with letting the user move the view around freely in the coordinate. Currently with mouseDragged the user can drag the view around a bit, but once the user releases the mouse and tries to move the view again the origin snaps back to the current position of the mouse cursor. What is the best way to let the user move around freely? Thanks in advance!
Here's the code for the drawing area.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JPanel;
public class DrawingArea extends JPanel implements MouseMotionListener {
private final int x_panel = 350; // width of the panel
private final int y_panel = 400; // height of the panel
private int div_x; // width of one square
private int div_y; // height of one square
private int real_y;
private int real_x;
private Point origin; // the origin of the coordinate
private Point temp; // temporary point
private static int y = 0;
private static int x = 0;
DrawingArea() {
setBackground(Color.WHITE);
real_x = x_panel;
real_y = y_panel;
setDivisionDefault();
setOrigin(new Point((real_x / 2), (real_y / 2)));
setSize(x_panel, y_panel);
addMouseMotionListener(this);
}
DrawingArea(Point origin, Point destination) {
this.origin = origin;
this.destination = destination;
panel = new JPanel();
panel.setSize(destination.x, destination.y);
panel.setLocation(origin);
this.panel.setBackground(Color.red);
panel.setLayout(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D line = (Graphics2D) g;
temp = new Point(origin.x, origin.y);
line.setColor(Color.red);
drawHelpLines(line);
line.setColor(Color.blue);
drawOrigin(line);
line.setColor(Color.green);
for (int i = 0; i < 100; i++) { // This is a test line
//temp = this.suora();
temp.x++;
temp.y++;
line.drawLine(temp.x, temp.y, temp.x, temp.y);
}
}
public void setOrigin(Point p) {
origin = p;
}
public void drawOrigin(Graphics2D line) {
line.drawLine(origin.x, 0, origin.x, y_panel);
line.drawLine(0, origin.y, x_panel, origin.y);
}
public void drawHelpLines(Graphics2D line) {
int xhelp= origin.x;
int yhelp= origin.y;
for (int i = 0; i < 20; i++) {
xhelp+= div_x;
line.drawLine(xhelp, 0, xhelp, y_panel);
}
xhelp= origin.x;
for (int i = 0; i < 20; i++) {
xhelp-= div_x;
line.drawLine(xhelp, 0, xhelp, y_panel);
}
for (int i = 0; i < 20; i++) {
yhelp-= div_y;
line.drawLine(0, yhelp,x_panel, yhelp);
}
yhelp= origin.y;
for (int i = 0; i < 20; i++) {
yhelp+= div_y;
line.drawLine(0, yhelp, x_panel, yhelp);
}
}
public void setDivisionDefault() {
div_x = 20;
div_y = 20;
}
#Override
public void mouseDragged(MouseEvent e) {
//Point temp_point = new Point(mouse_x,mouse_y);
Point coords = new Point(e.getX(), e.getY());
setOrigin(coords);
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
Based on this example, the following program allows the user to drag the axes' intersection to an arbitrary point, origin, which starts at the center of the panel.
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* #see https://stackoverflow.com/a/15576413/230513
* #see https://stackoverflow.com/a/5312702/230513
*/
public class MouseDragTest extends JPanel {
private static final String TITLE = "Drag me!";
private static final int W = 640;
private static final int H = 480;
private Point origin = new Point(W / 2, H / 2);
private Point mousePt;
public MouseDragTest() {
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
this.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mousePt = e.getPoint();
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
int dx = e.getX() - mousePt.x;
int dy = e.getY() - mousePt.y;
origin.setLocation(origin.x + dx, origin.y + dy);
mousePt = e.getPoint();
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, origin.y, getWidth(), origin.y);
g.drawLine(origin.x, 0, origin.x, getHeight());
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame(TITLE);
f.add(new MouseDragTest());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
I am developing a game and in some part of my game I want the rectangle to disappear on mouse release. I have placed 26 rectangles in an arrayList and remove the particular rectangle clicked as the mouse is released. So if I remove the fill methods, the rectangle disappears successfully but if the fill methods are there, it does not work anymore.
Here is my paint method:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.draw(s);
}
g2.setColor(bColor);
g2.fill(box1);
g2.fill(box2);
g2.fill(box3);
g2.fill(box4);
g2.fill(box5);
g2.fill(box6);
g2.fill(box7);
g2.fill(box8);
g2.fill(box9);
g2.fill(box10);
g2.fill(box11);
g2.fill(box12);
g2.fill(box25);
g2.setColor(wColor);
g2.fill(box13);
g2.fill(box14);
g2.fill(box15);
g2.fill(box16);
g2.fill(box17);
g2.fill(box18);
g2.fill(box19);
g2.fill(box20);
g2.fill(box21);
g2.fill(box22);
g2.fill(box23);
g2.fill(box24);
g2.fill(box26);
}
Here is how I did the removing of the rectangle (Just an excerpt):
if (box1.getBounds().contains(x, y)) {
pickedPanelNum = 0;
rectanglesList.remove(box1);
panelsPane.repaint();
}
Here are the values of the bColor and wColor:
Color bColor = Color.BLACK;
Color wColor = Color.WHITE;
NOTE:
The pickedPanelNum is just for assigning an int value and has no connection to the problem.
I think it is because when I repaint, the fill methods are still there. However I have no idea for an alternate way of painting the rectangles.
I hope my problem is stated clearly. If you have ideas how I could solve this, please tell me. Thank you!
UPDATE:
Here is a shorter, runnable version of my program. (Background image isn't included though):
import java.awt.*;
import java.awt.Color.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.geom.Rectangle2D;
public class Rec extends JComponent
{
public ArrayList<Rectangle> rectanglesList = new ArrayList<Rectangle>();
public int arrx[] = new int[120];
public int arry[] = new int[120];
JFrame frame = new JFrame();
public int xSize = 2000;
public int ySize = 1000;
public int x;
public int y;
public int pickedPanelNum = 0;
public String pickedPanelDash = "";
public String pickedPanelColor = "";
Color bColor = Color.BLACK;
Color wColor = Color.WHITE;
boolean removedPanel = false;
public void launchFrame()
{
Random rand = new Random();
for(int x = 0;x<120;x++)
{
arrx[x] = rand.nextInt(640);
arry[x] = rand.nextInt(590);
}
Rectangle box1 = new Rectangle(arrx[103],arry[59],80,90);
Rectangle box2 = new Rectangle(arrx[105],arry[3],80,90);
rectanglesList.add(box1);
rectanglesList.add(box2);
JPanel mainPanel = new JPanel();
JPanel panelsPane = new JPanel()
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.draw(s);
}
g2.setColor(bColor);
g2.fill(box1);
g2.setColor(wColor);
g2.fill(box2);
}
};
JPanel rightPane = new JPanel();
panelsPane.addMouseListener (new MouseAdapter ()
{
public void mousePressed(MouseEvent event)
{
x = event.getX();
y = event.getY();
}
public void mouseReleased(MouseEvent event)
{
if (box1.getBounds().contains(x, y)) {
pickedPanelNum = 0;
rectanglesList.remove(box1);
panelsPane.repaint();
}
if (box2.getBounds().contains(x, y)) {
pickedPanelNum = 1;
rectanglesList.remove(box2);
panelsPane.repaint();
}
}
});
panelsPane.addMouseMotionListener (new MouseAdapter ()
{
public void mouseDragged(MouseEvent event)
{
Rec obj = new Rec();
int dx = event.getX() - x;
int dy = event.getY() - y;
if (box1.getBounds().contains(x, y)) {
box1.x += dx;
box1.y += dy;
panelsPane.repaint();
}
if (box2.getBounds().contains(x, y)) {
box2.x += dx;
box2.y += dy;
panelsPane.repaint();
}
x += dx;
y += dy;
}
public void mouseReleased(MouseEvent event) {}
public void mouseClicked(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
});
panelsPane.setPreferredSize(new Dimension (800, ySize-315));
rightPane.setPreferredSize(new Dimension (530, ySize-315));
mainPanel.setPreferredSize(new Dimension (xSize, ySize));
frame.setPreferredSize(new Dimension (xSize, ySize));
rightPane.setBackground(Color.gray);
mainPanel.add(panelsPane);
mainPanel.add(rightPane);
frame.add(mainPanel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
}
public static void main(String args[])
{
Rec obj = new Rec();
obj.launchFrame();
}
}
Even if you remove box1 from the List, there is nothing stopping it from getting filled in your paintComponent method, the for-loop is only drawing the outline of the rectangles within the list, but you code implicitly fills them anyway.
So, first, get rid of all the box{n} variables. Next change the paintComponent method...
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
//g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.setColor(bColor);
g2.fill(s);
g2.setColor(wColor);
g2.draw(s);
}
}
So, this just uses the rectanglesList to first draw the rectangles and the fill them
Then, lets update the mouseReleased...
public void mouseReleased(MouseEvent event) {
// Because the rectangles are painted in order, the later
// rectangles are painted over the eailer ones, so, we reverse
// the list so we can check for the higher positioned
// rectangles
List<Rectangle> copy = new ArrayList<>(rectanglesList);
Collections.reverse(copy);
for (Rectangle r : copy) {
if (r.contains(event.getPoint())) {
rectanglesList.remove(r);
break;
}
}
event.getComponent().repaint();
}
Okay, this is little more funky, but basically, we reverse the list of rectangles (because those rectangles that appear later in the list are painted over those that appear before them) and checks to see if the mouse was clicked within any one of them. The moment we find a match, we break out of the loop and repaint the component which generated the event
And, because it's nice to see this stuff running, a complete example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Rec extends JComponent {
public ArrayList<Rectangle> rectanglesList = new ArrayList<Rectangle>();
public int arrx[] = new int[120];
public int arry[] = new int[120];
JFrame frame = new JFrame();
public int xSize = 2000;
public int ySize = 1000;
public int x;
public int y;
public int pickedPanelNum = 0;
public String pickedPanelDash = "";
public String pickedPanelColor = "";
Color bColor = Color.BLACK;
Color wColor = Color.WHITE;
boolean removedPanel = false;
public void launchFrame() {
Random rand = new Random();
for (int x = 0; x < 10; x++) {
arrx[x] = rand.nextInt(640);
arry[x] = rand.nextInt(590);
rectanglesList.add(new Rectangle(arrx[x], arry[x], 80, 90));
}
JPanel mainPanel = new JPanel();
JPanel panelsPane = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Image img = Toolkit.getDefaultToolkit().getImage(Rectangles2.class.getResource("background.jpg"));
// g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle s : rectanglesList) {
g2.setColor(bColor);
g2.fill(s);
g2.setColor(wColor);
g2.draw(s);
}
}
};
JPanel rightPane = new JPanel();
panelsPane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
x = event.getX();
y = event.getY();
}
public void mouseReleased(MouseEvent event) {
// Because the rectangles are painted in order, the later
// rectangles are painted over the eailer ones, so, we reverse
// the list so we can check for the higher positioned
// rectangles
List<Rectangle> copy = new ArrayList<>(rectanglesList);
Collections.reverse(copy);
for (Rectangle r : copy) {
if (r.contains(event.getPoint())) {
rectanglesList.remove(r);
break;
}
}
event.getComponent().repaint();
}
});
panelsPane.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseClicked(MouseEvent event) {
}
public void mouseEntered(MouseEvent event) {
}
public void mouseExited(MouseEvent event) {
}
});
panelsPane.setPreferredSize(new Dimension(800, ySize - 315));
rightPane.setPreferredSize(new Dimension(530, ySize - 315));
mainPanel.setPreferredSize(new Dimension(xSize, ySize));
frame.setPreferredSize(new Dimension(xSize, ySize));
rightPane.setBackground(Color.gray);
mainPanel.add(panelsPane);
mainPanel.add(rightPane);
frame.add(mainPanel);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
}
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();
}
Rec obj = new Rec();
obj.launchFrame();
}
});
}
}
I'm designing an interface using java swing. There is a canvas for the user to draw shapes (circle, triangle, square, etc.). When the user draws a shape, I want to name each point in the shape alphabetically. I know how to get the coordinates but how do I name the points?
Here is one way to do it. You use Character.toString(char) and use 'A'+offset to get any char from the alphabet.
See in this small demo example, which draws polygons.
Single click creates vertices of your polygon
Double-click stores the current polygon and starts creating a new polygon
Right-click clears the current polygon and starts a new one.
Side-note: positioning of the text is not smart, so it overlaps lines of the polygon sometimes.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseAdapter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestNaming {
private static final int PANEL_WIDTH = 600;
private static final int PANEL_HEIGHT = 600;
public static class Drawing extends JPanel {
private static final Font FONT = new Font("Arial", Font.PLAIN, 12);
private List<Polygon> polygons = new ArrayList<Polygon>();
private Polygon currentPolygon = new Polygon();
private MouseAdapter mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
if (e.getClickCount() == 1) {
addPoint(e.getX(), e.getY());
} else if (e.getClickCount() == 2) {
createPolygon();
}
} else if (SwingUtilities.isRightMouseButton(e)) {
clearCurrentPolygon();
}
}
};
public Drawing() {
addMouseListener(mouseListener);
}
protected void addPoint(int x, int y) {
currentPolygon.addPoint(x, y);
repaint();
}
protected void clearCurrentPolygon() {
currentPolygon = new Polygon();
repaint();
}
protected void createPolygon() {
if (currentPolygon.npoints > 2) {
polygons.add(currentPolygon);
}
clearCurrentPolygon();
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PANEL_WIDTH, PANEL_HEIGHT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.setFont(FONT);
for (Polygon polygon : polygons) {
drawPolygon(g, polygon);
}
g.setColor(Color.GREEN);
drawPolygon(g, currentPolygon);
}
private void drawPolygon(Graphics g, Polygon polygon) {
if (polygon.npoints < 3) {
if (polygon.npoints == 1) {
g.fillOval(polygon.xpoints[0] - 2, polygon.ypoints[0] - 2, 4, 4);
drawNthPoint(g, polygon, 0);
} else if (polygon.npoints == 2) {
g.drawLine(polygon.xpoints[0], polygon.ypoints[0], polygon.xpoints[1], polygon.ypoints[1]);
drawNthPoint(g, polygon, 0);
drawNthPoint(g, polygon, 1);
}
} else {
g.drawPolygon(polygon);
for (int i = 0; i < polygon.npoints; i++) {
drawNthPoint(g, polygon, i);
}
}
}
private void drawNthPoint(Graphics g, Polygon polygon, int nth) {
// Only works 26 times!
String name = Character.toString((char) ('A' + nth));
int x = polygon.xpoints[nth];
int height = g.getFontMetrics().getHeight();
int y = polygon.ypoints[nth] < height ? polygon.ypoints[nth] + height : polygon.ypoints[nth];
g.drawString(name, x, y);
}
}
protected static void initUI() {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Drawing());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initUI();
}
});
}
}
If I'm understanding you correctly, you want to label the coordinates alphabetically (like A, B, C, D)
Since you said you know the coordinates already...use a JLabel:
JLabel A_label = new JLabel("A");
JLabel B_label = new JLabel("B");
A_label.setLocation(shape1_x, shape1_y);
B_label.setLocation(shape2_x, shape2_y);
I'm trying to build a custom triangle component that has the same features as a JComponent (like a JButton per say).
The porpoise of the program will be to add triangle on a mouse click exactly where the mouse is and to handle a mouseover event by highlighting the bg of the shape.
I let the default layouts(or null), because while using others, the applications just doesn't place the triangles where I want...
Right now my major issue is how to adjust the size of the triangles with direct proportionality relative to the form size? So that if I reduce the frame size 50% all the components are down that value as well.
One other issue is that the JComponent requires a rectangular area to handle events, for what I've seen there's no way countering this, so if I try to click on the affected area it will just ignore it instead of creating a new triangle there.
And yet another problem is that sometimes while moving out of the triangle from the bottom it is still green.
Thanks!
Here is the SSCCE:
// TriangleCustom.java
package TriangleCustom;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TriangleCustom {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame f = new JFrame("Triangle");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1200, 800);
Panel p = new Panel();
f.add(p);
f.setVisible(true);
}
}
class Panel extends JPanel {
// the offsets are the area (rect border) to contain the triangle shape
private final int xOFFSET = 25;
private final int yOFFSET = 50;
ArrayList<TriangleShape> triangleAL = new ArrayList<TriangleShape>();
public Panel() {
setBounds(0, 0, 800, 400);
// setBorder(BorderFactory.createLineBorder(Color.black,2));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
addTriangle(new Point(e.getX(), e.getY()), new Point(e.getX()
- xOFFSET, e.getY() + yOFFSET), new Point(e.getX()
+ xOFFSET, e.getY() + yOFFSET));
}
});
}
private void addTriangle(Point topCorner, Point leftCorner,
Point rightCorner) {
final TriangleDTO tdto = new TriangleDTO(new Point(25, 0), new Point(0,
50), new Point(50, 50));
TriangleShape ts = new TriangleShape(tdto);
ts.setBorderColor(Color.BLACK);
ts.setFillColor(Color.RED);
ts.setBounds((int) (topCorner.getX() - 25), (int) topCorner.getY(), 51,
51);
triangleAL.add(ts);
this.add(ts);
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.draw(new Rectangle2D.Double(0, 0, 799, 399));
}
}
// the custom component in a shape of a triangle
class TriangleShape extends JComponent {
private GeneralPath triangle = new GeneralPath();
private TriangleDTO tdto = new TriangleDTO();
private Color borderColor = new Color(0);
private Color fillColor = new Color(0);
// Constructor
public TriangleShape(TriangleDTO tdto) {
this.tdto = tdto;
triangle.moveTo(tdto.getTopCorner().getX(), tdto.getTopCorner().getY());
triangle.lineTo(tdto.getLeftCorner().getX(), tdto.getLeftCorner()
.getY());
triangle.lineTo(tdto.getRightCorner().getX(), tdto.getRightCorner()
.getY());
triangle.closePath();
addMouseMotionListener(new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
// there are some issues when going out of the triangle from
// bottom
if (triangle.contains((Point2D) e.getPoint())) {
setFillColor(Color.GREEN);
repaint();
} else {
setFillColor(Color.RED);
repaint();
}
}
});
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
public void setFillColor(Color fillColor) {
this.fillColor = fillColor;
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(fillColor);
g2d.fill(triangle);
g2d.setPaint(borderColor);
g2d.draw(triangle);
}
}
// just a plain DTO for the triangle points
class TriangleDTO {
private Point topCorner = new Point();
private Point leftCorner = new Point();
private Point rightCorner = new Point();
// Constructors
public TriangleDTO() {
}
public TriangleDTO(Point topCorner, Point leftCorner, Point rightCorner) {
super();
this.topCorner = topCorner;
this.leftCorner = leftCorner;
this.rightCorner = rightCorner;
}
// Getters and Setters
public Point getTopCorner() {
return topCorner;
}
public void setTopCorner(Point topCorner) {
this.topCorner = topCorner;
}
public Point getLeftCorner() {
return leftCorner;
}
public void setLeftCorner(Point leftCorner) {
this.leftCorner = leftCorner;
}
public Point getRightCorner() {
return rightCorner;
}
public void setRightCorner(Point rightCorner) {
this.rightCorner = rightCorner;
}
}
i am try to make chorded keyboard simulation.
I cannot resolve why KeyboardButtons in Keyboard are not painting. I have more KeyboardButtons in Keyboard. Mouse is listened properly, but polygons are not painted.
When i call paint to each KeyboardButton in the Keyboard's paintComponent(), polygons are painted, but not changing color on mousePressed.
Keyboard.java
package keyboard;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComponent;
import javax.swing.JPanel;
public class Keyboard extends JPanel implements MouseListener{
Point[] leftFingers;
Point leftCenter = new Point(300, 600);
KeyboardButton[] buttons;
public Keyboard(Point left1, Point left2, Point left3, Point left4, Point left5) {
leftFingers = new Point[5];
leftFingers[0] = left1;
leftFingers[1] = left2;
leftFingers[2] = left3;
leftFingers[3] = left4;
leftFingers[4] = left5;
buttons = registerKeys();
addMouseListener(this);
}
public KeyboardButton[] registerKeys() {
Polygon[] polygons = generateKeyPolygons(calculateBordersOfKeys(leftFingers));
KeyboardButton[] buttons = new KeyboardButton[5];
for (int i = 0; i < polygons.length; i++) {
buttons[i] = new KeyboardButton(polygons[i]);
}
return buttons;
}
private Point[] calculateBordersOfKeys(Point[] fingers) {
Point[] centers = calculateCentersBetweenEachTwoFingers(fingers);
Point[] result = new Point[6];
result[0] = calculateCentralSymmetry(centers[0], fingers[0]);
System.arraycopy(centers, 0, result, 1, centers.length);
result[5] = calculateCentralSymmetry(centers[3], fingers[4]);
return result;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.drawOval(leftCenter.x - 25, leftCenter.y - 25, 50, 50);
for (int i = 0; i < leftFingers.length; i++) {
g.drawOval(leftFingers[i].x, leftFingers[i].y, 10, 10);
}
}
private Polygon[] generateKeyPolygons(Point[] borders) {
Polygon[] polygons = new Polygon[5];
for (int i = 0; i < borders.length - 1; i++) {
Polygon p = new Polygon();
p.addPoint(leftCenter.x, leftCenter.y);
p.addPoint(borders[i].x, borders[i].y);
p.addPoint(borders[i + 1].x, borders[i + 1].y);
polygons[i] = p;
}
return polygons;
}
private Point[] calculateCentersBetweenEachTwoFingers(Point[] fingers) {
Point[] centers = new Point[4];
for (int i = 0; i < fingers.length - 1; i++) {
centers[i] = new Point(((fingers[i].x + fingers[i + 1].x) / 2), ((fingers[i].y + fingers[i + 1].y) / 2));
}
return centers;
}
private Point calculateCentralSymmetry(Point toReflected, Point center) {
Point reflection = new Point();
if (toReflected.x > center.x) {
reflection.x = center.x - Math.abs(center.x - toReflected.x);
} else {
reflection.x = center.x + Math.abs(center.x - toReflected.x);
}
if (toReflected.y > center.y) {
reflection.y = center.y - Math.abs(center.y - toReflected.y);
} else {
reflection.y = center.y + Math.abs(center.y - toReflected.y);
}
return reflection;
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
for (KeyboardButton button : buttons) {
button.checkMousePosition(e);
}
}
public void mouseReleased(MouseEvent e) {
for (KeyboardButton button : buttons) {
button.checkMousePosition(e);
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
KeyboardButton.java
package keyboard;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.*;
import javax.swing.JComponent;
import javax.swing.JPanel;
public class KeyboardButton extends JComponent {
Polygon polygon;
boolean isActive;
final Color ACTIVE_COLOR = Color.red;
final Color INACTIVE_COLOR = Color.blue;
public KeyboardButton(Polygon p) {
polygon = p;
}
public void checkMousePosition(MouseEvent e) {
if (polygon.contains(e.getX(), e.getY())) {
setState(true);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(isActive ? ACTIVE_COLOR : INACTIVE_COLOR);
g.drawPolygon(polygon);
}
void setState(boolean state) {
isActive = state;
System.out.println(this.hashCode());
repaint();
}
}
As far as I can tell, the KeyboardButton components are never added to the Keyboard. So, when they call repaint(), it has no effect because they are not part of the view hierarchy.