Helo guys,
my problem is that sometimes if my Rectangle2D gets a big width or height its bottom,left border splits and no longer makes a continous border and if I even make it wider the border goes smaller and smaller, like if there were a limitation of how long a rectangles border can be... It is really confusing and so far I have not found the solution :S I put there a link to a picture so you can see for yourself.
new Rectangle2D.Double(mojrectangle.getUpperleftPointmojRectangle().getX(), mojrectangle.getUpperleftPointmojRectangle().getY(),1000,1000)
repaint();
thanks for your help..
BTW I have the same problem with Arc2D if it gets really big
UPDATE: I removed from the function the setStroke command and now it draws it correctly, but in the future I will need to set the Rectangles stroke so it leaves me sad.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
//g2.setStroke(stroke);
g2.draw(rectangle);
}
Here I put an example code of my project, please try it with g2.setStroke(selectedstroke)- it wont work, and without it...I hope I explained myself clear .
package com.awtgraphicsdemo;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.JComboBox;
public class AWTgraphicsdemo extends Frame {
final float dash[] = {10.0f};
final float solid[] = {1000.0f}; // these must be in an Array
float lineWidth[]={2.0f,4.0f,6.0f,8.0f,10.0f}; // width of the drawing line
String[] lineWidthString={"2.0","4.0","6.0","8.0","10.0"};
JComboBox strokecombobox=new JComboBox(lineWidthString);
BasicStroke selectedStroke = new BasicStroke(lineWidth[0],BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER, 10.0f, solid, 0.0f);
public AWTgraphicsdemo(){
super("Java AWT Examples");
prepareGUI();
}
public static void main(String[] args){
AWTgraphicsdemo awtGraphicsDemo = new AWTgraphicsdemo();
awtGraphicsDemo.setVisible(true);
}
private void prepareGUI(){
setSize(400,400);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(selectedStroke);
g2.draw (new Rectangle2D.Double(10, 10, 1000, 900));
Font font = new Font("Serif", Font.PLAIN, 24);
g2.setFont(font);
g.drawString("Welcome to TutorialsPoint", 50, 70);
g2.drawString("Rectangle2D.Rectangle", 100, 120);
}
}
Helo again,
I figured out my problem, it was in the properties of stroke,so after some lenght of the compoment the stroke got activated which made changed to the drawn shape.By modifying the strokes solid array I was able the get the result I wanted.
Thank you for your help and suggestions :)
Take Care
Better to:
Not override paint(...) in top level windows (as MadProgrammer states) since this also changes painting of borders and child components -- a dangerous thing to do.
Instead override paintComponent(...) of a JPanel (again as MadProgrammer states) and place that JPanel into your top level window.
Don't set the Stroke of the Graphics object passed into your painting method, but rather a copy of the Graphics object so not to have side effects down the road.
e.g.,
public class MyPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(....);
// do drawing with g2 here
g2.dispose();
}
}
Related
I'm making a simple 2-D game for which I'd like to move the camera with the mouse. There are loads of better ways to do this, I'm sure, but I decided to try out the Graphics2D method setTransform().
AffineTransform at = new AffineTransform();
at.translate(mousex, 0);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setTransform(at);
However, the graphics don't translate linearly with the mouse, as you can see from the images below. For the first few pixels it seems to move correctly, but it kind of slows down later?
By the way, the mouse is indicated by the blue circle.
When the mouse is near the edge of the frame, the graphics moves almost linearly with it to the right.When the mouse is dragged further to the right, the graphics moves with it, but with a kind of lag (it shouldn't)
The white border around the blocks represents the outline of the graphics that should be moving.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class Bruh extends JPanel implements MouseMotionListener
{
int mousex = 0;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setUndecorated(true);
f.add(new Bruh());
f.setVisible(true);
}
Bruh()
{
setBackground(Color.ORANGE);
addMouseMotionListener(this);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
AffineTransform at = new AffineTransform();
at.translate(mousex, 0);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setTransform(at);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 100, 100, 100);
g2d.dispose();
g.setColor(Color.BLUE);
g.fillOval(mousex-5, 200-5, 10, 10);
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
mousex = e.getX();
}
#Override
public void mouseMoved(MouseEvent e) {
mousex = e.getX();
}
}
TL;DR
The setTransform(AffineTransform at) function of Graphics2D isn't working as intended. Any help is appreciated :)
Okay so I got the answer. The problem isn't in my code, or with my touchpad scrolling.
On my laptop, I had set the scaling of the display to 125%, causing everything to work normally EXCEPT apps that use default scaling - Java being one of them.
The problem was that my mouse moved correctly (because that's what mice do) but the in-built graphics of java were responding to the default scaling of the display i.e. 125%. So everything was moving 1.25 times slower than expected.
Hi i am a beginner in java, here I have my program, however, when I try resizing the panel my text just disappears?
Moreover, how can i draw a thick green line under my text which will stay under the text even when resizing, I am very clueless?
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
public class Groovy
{
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame= new JFrame("Shearing Word Demo");
frame.setResizable(true);
frame.setSize(new Dimension(500,250));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Toolkit it=Toolkit.getDefaultToolkit();
Dimension d=it.getScreenSize();
int w=frame.getWidth(), h=frame.getHeight();
frame.setLocation(d.width/2-w/2, d.height/2-h/2);
frame.add(new JComponent(){
#Override public void paintComponent(Graphics g){
Graphics2D g2=(Graphics2D) g;
g2.setColor(Color.magenta);
g2.setFont(new Font("Comic Sans MS",Font.BOLD,44));
g2.drawString("Feeling Groovy!", 110,125 );
}
});
frame.setVisible(true);
}
});
}
}
how can i draw a thick green line under my text which will stay under the text even when resizing, I
If you do custom painting then the basic steps you need to follow would be something like:
get the FontMetrics of the Graphics object using the getFonTMetrics() method
get the rectangle of text using the getStringBounds(...) method
use the setStroke(...) method of the Graphics2D object to set the thickness of the line to paint
use the drawLine(...) method Graphics2D object to paint the line based on the location of the text and the information of the Rectangle from the string bounds
An easier solution for displaying text is to use a JLabel. Then you can set the Border of the label. Read the section from the Swing tutorial on How to Use Borders for more information.
Note when doing custom painting with a JComponent you are also responsible for clearing the background of the component. So the first painting in the method should be:
g2.setColor( getBackground() );
g2.fillRect(0, 0, getWidth(), getHeight());
Most people use a JPanel for custom painting then you can just use:
super.paintComponent(g);
to make sure the background is cleared.
So in the past few days I've tried to implement an easier version of a graph plotter.
One big problem I was confronted with was a bug that occured on repainting.
Basically I've designed my program in one class which is responsible for drawing the whole coordinate system and the given function after clicking a JButton in an other class. The other class contains the JButton which is pressed. After pressing the JButton it calls a function in the coordinate system class which repaints the picture. Both of those classes are extending JPanel.
The bug was that when I was doing the repainting on pressing the button, the button was drawn on the coordinate System and not in its original place, so in other words on the other JPanel even though I didn't change a thing about placements and stuff. Both classes were added to a JFrame which use a GridLayout.
Can anyone tell me why super.paintComponent(g); solved that bug?
Edit: Added Code
Window class
public class main {
public static void main(String[] args) throws SemanticFailureException {
int x = 800;
int y = 600;
JFrame frame = new JFrame();
frame.setLayout(new GridLayout());
frame.setTitle("Function plotter");
frame.setSize(2*x, 2*y);
Surface test = new Surface(x, y, 10);
CommandDraw test1 = new CommandDraw(x/2,y,test);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(test);
frame.add(test1);
frame.setVisible(true);
}
}
Coordinate System class: (changed drawing the coordinate system to a rectangle for simplicity, the bug still occures with only drawing a rectangle)
public class Surface extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
boolean drawFunct;
public Surface(int x1, int y1, int coordLength) {
setSize(x1,y1);
drawFunct = false;
}
public void paintComponent(Graphics g) {
super.paintComponent(g); // without this the jbutton occures on the left
// create Graphics object to get more functions
Graphics2D g2 = (Graphics2D) g;
// draw Plotter
drawFunction(g2);
if (drawFunct)
g2.drawLine(0, 0, 80, 80);
}
public void drawFunction(Graphics2D g) {
g.drawRect(40, 40, 30, 30);
}
public void redraw() {
drawFunct = true;
repaint();
}
}
The Class with the JButton:
public class CommandDraw extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
JButton makeDraw;
JTextField inputPoly;
Surface surf;
public CommandDraw(int x, int y, Surface surf) {
this.surf = surf;
setSize(x,y);
setLayout(new FlowLayout());
makeDraw = new JButton("draw Function");
makeDraw.setBackground(Color.LIGHT_GRAY);
makeDraw.setFocusable(false);
makeDraw.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
surf.redraw();
}
});
add(makeDraw);
inputPoly = new JTextField("Input polynomial");
inputPoly.setHorizontalAlignment(JTextField.CENTER);
add(inputPoly);
}
}
Can anyone tell me why super.paintComponent(g); solved that bug?
Because the call to paintComponent(g) of the superclass (JPanel) will guarantee that panel will be rendered as expected before you do your paint operations. You need to make sure that your JPanel will behave, in the Graphics perspective, like any other JPanel.
A template for a customized JPanel to draw should be something like:
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class MyDrawPanel extends JPanel {
#Override
protected void paintComponent( Graphics g ) {
super.paintComponent( g );
// create a new graphics context based on the original one
Graphics2D g2d = (Graphics2D) g.create();
// draw whatever you want...
g2d.dispose();
}
}
EDIT
You need to call super.paintComponent(g) to tell that the JPanel paintComponent(Graphics) version should be execute before you start doind your customized things. It's something like to ask the JPanel to prepare its paint capabilities to be used. A good starting point to these kind of doubts is the documentation: https://docs.oracle.com/javase/10/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)
The dispose() method is being called in the copy of the original Graphics. If you dispose the Graphics that is passed to the method, you may have some issues too. You could use the original Graphics to perform you painting operations, but you shouldn't, so a better practice is to make a copy of the original Graphics and dispose it after using.
Take a look here too: How does paintComponent work?
How can I draw a circle that is resizable when the window is maximized or minimized? The code I have isn't really even draw the circle like I would like it to either. Any help with this would be greatly appreciated as I have never worked with graphics in Java before and the Oracle site is only helping me so much. Thanks.
public class GUI extends JFrame {
public GUI() {
JPanel p1 = new JPanel();
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawOval(0, 0, 50, 50);
}
public static void main(String[] args) {
GUI frame = new GUI();
frame.setTitle("Circle Generator");
frame.setSize(400, 300);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
To make the painting dynamic you need to get the current width/height of the panel.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//g2d.drawOval(0, 0, 50, 50);
g2d.drawOval(0, 0, getWidth(), getHeight());
}
You also need the super.paintComponent(g) to clear the background of the panel.
Edit:
Actually, I took a closer look at your code and it does nothing. A JFrame does not have a paintComponent() method so your code will never be executed. Also, you create a panel but then don't do anything with it.
Start by reading the section from the Swing tutorial on Custom Painting for more information and working examples.
Then you can modify the example from the tutorial to draw your oval, using the suggestion give above.
This is a pretty simple program that just draws a white rectangle in a pop-up window. The program compiles and runs no problem, and the windoe pops up, but there is nothing in it, it's just grey. Why isn't anything drawing?
import java.awt.*;
import javax.swing.*;
public class DrawPanel extends JPanel {
public void paintcompnent(Graphics g) {
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(10, 10, 200, 200);
}
public static void main(String[] args) {
DrawPanel panel = new DrawPanel();
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(panel);
window.setSize(550,550);
window.setVisible(true);
}
}
public void paintcompnent(Graphics g)
Should be
public void paintComponent(Graphics g)
You have not correctly overridden the method. It should be:
#Override
protected void paintComponent(Graphics g) {}
Note the use of the #Override annotation, which will prevent you from making this mistake in the future.
After fixing the overridden method name, it still won't paint anything because you are filling the rectangle in white and then painting white lines on top. You need to use setColor() to set something other than white to see the lines.