i tried making a program that will create a visual every time you click, but it didnt work so i stripped down the code to a sample of what didnt work.
at first i thought that the problem was that i didnt have a draw function so processing didnt search for events but when i added the println it still didnt trigger...
can you help me find where i was wrong??
void setup(){
size(500, 400);
}
void draw(){;} // listens to events
void mouseClicked(){
println("d");
}
edit1: goldenCucumber told me to get rid of two curly braces, i forgot to delete them (i dont think this is the problem)
edit2:
people asked for the full code:
void setup(){
size(500, 400);
colorMode(HSB, 100);
draw_gradients();
}
void draw_gradients(){
color c1 = color(random(100), 100, 100);
color c2 = color(random(100), 100, 30);
for(int y = 0; y < height;y++){
float n = map(y, 0, height, 0, 1);
color newc = lerpColor(c1, c2, n);
stroke(newc);
line(0, y, width, y);
n += 0.01;
}
}
void draw(){;} // listens to events
void mouseClicked(){
println("d");
draw_gradients();
}
If you remove two unnecessary "}" signs after "size(500, 400);" it works correctly, just tested. I am not sure though if you are aware that println() function only prints text to Processing console in the bottom of the code window. It does not draw it in animation window.
Related
So I'm working on a somewhat interactive painting of a chess game. Basically, for now, there are only 2 buttons: next move and previous move. The next move button adds 1 to the int variable moveNum, and the previous move button subtracts 1 from the int variable moveNum. Basically like this:
int moveNum = 0;
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Next Move"))
{
moveNum++;
Display.instance.repaint();
}
else if(e.getActionCommand().equals("Previous Move"))
{
moveNum--;
Display.instance.repaint();
}
}
I then just have a ton of graphics, one for each value of moveNum. It looks somewhat like this:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.BLACK);
if (moveNum == 0)
{
g2d.fill(new Rectangle2D.Double(0, 0, 10, 10));//just for simplicity
}
else if (moveNum == 1)
{
g2d.fill(new Rectangle2D.Double(0, 0, 10, 10));
g2d.fill(new Rectangle2D.Double(0, 0, 20, 10)); //again for simplicity
}
else if (moveNum ==2)
{
g2d.fill(new Rectangle2D.Double(0, 0, 10, 10));
g2d.fill(new Rectangle2D.Double(0, 0, 20, 10));
g2d.fill(new Rectangle2D.Double(0, 0, 30, 10)); //simplicity
}
...
}
But the graphics are not changing when I press the buttons. What could I be missing?
Update: I have tried to call Display.instance.repaint() after the moveNum stuff, but now I get no graphics at all. What could be the problem?
Update #2: The paint component is being executed because when I put System.out.println("Test"); to the method, it is being printed. I also now see the infinite recursion problem (not sure how I did not see it before). But even after fixing it, I still don't get the graphics I want. I realized that I can get some graphics when I go full-screen for some reason. But the buttons still don't change the graphics. Using the System.out.println("Test"); method, I found that "Test" is printed once when I run the program, two more times when I go full screen and get graphics, and 12 more times when I press the next button. I'm not really sure what's going on there, are my buttons set up incorrectly?
Final update: I do not have a MRE/SSCE, but I have figured out my problem. I have realized I'm one of the biggest idiots in the universe and my problem was capitalization. My buttons were not working because I capitalized the wrong thing in both of them in the segment e.getActionCommand().equals("Next Move")). Anyways, thanks a ton for your help. I don't think I would have found the infinite recursion problem, so special thanks for helping with that.
Try adding component.repaint() after moveNum++; and after moveNum--;.
When component is the component that you want to update.
Also, remove the repaint() inside paintComponent(Graphics g)
I'm doing a project for school in witch I have to simulate an ant colony and also show it in a graphics user interface.
The whole project is almost complete but I neet to implement a zoom feature for my jPanel.
I've found a thread on this site with basically what I need.Here's the link:
Zooming in and zooming out within a panel
What Thanasis made in that thread is what I basically need but I have no Idea how to implement it inside my code with the other classes.
I am a newbie in Graphic User Interface and we are basically learning and understanding it by doing this project so forgive me if the answer is Super easy and I'm asking for the answer.
I can provide code for the Pannel and Window classes.
I've allready tried launching it without anything thinking that it will work directly on my jpanel but it didn't of course.also tried to call it in my main but that didn't work either. Here's my paintComponent from my panel . I basically do this for everything that shows(ants, colony, food).
public void paintComponent(Graphics g){
int tailletab = this.gri.getTab().length;
//On récupère le tableau de la Grille
int[][] gril = this.gri.getTab();
int taillecarre;
int xcol = this.colo.getPos().getX();
int ycol = this.colo.getPos().getY();
int xsou = this.source.getPos().getX();
int ysou = this.source.getPos().getY();
if(tailletab<=50){
taillecarre = tailletab/4+2;
}else{
if(tailletab<60){
taillecarre = tailletab/5+1;
}else{
if(tailletab<70){
taillecarre = tailletab/7+1;
}else{
if(tailletab<80){
taillecarre = tailletab/8;
}else{
if(tailletab<90){
taillecarre = tailletab/10;
}else{
taillecarre = tailletab/13;
}
}
}
}
}
for(int i=0; i<tailletab; i++){
for(int j=0; j<tailletab; j++){
if(gril[j][i]==0){
if(j==xcol && i==ycol){
g.setColor(new Color(102, 51, 0));
g.fillRect(xcol*taillecarre, ycol*taillecarre,taillecarre,taillecarre);
g.setColor(Color.BLACK);
g.drawRect(xcol*taillecarre, ycol*taillecarre,taillecarre,taillecarre);
}else{
if(j==xsou && i==ysou){
g.setColor(Color.RED);
g.fillRect(xsou*taillecarre, ysou*taillecarre,taillecarre,taillecarre);
g.setColor(Color.BLACK);
g.drawRect(xsou*taillecarre, ysou*taillecarre,taillecarre,taillecarre);
}else{
g.setColor(Color.BLACK);
g.drawRect(j*taillecarre, i*taillecarre, taillecarre, taillecarre);
}
}
}else{
g.setColor(Color.BLACK);
g.drawRect(j*taillecarre, i*taillecarre, taillecarre, taillecarre);
g.fillRect(j*taillecarre, i*taillecarre, taillecarre, taillecarre);
}
}
}
}
The answer of Andreas Holstenson in the link you provided is better than Thanasis' because you shouldn't override paint but paintComponent as you correctly did, and Thanasis doesn't overwrite the transformation but tries to be dumb-clever about not progressively updating the transform. If you lost me, just forget that answer altogether.
Otherwise, the choice of whether to use AffineTransform or not does not matter as the result is the same. Arguably, AffineTransform is easier to use.
To answer your question, put the additional scale/translate code at the top of that method and all graphics drawn after that should be zoomed (even if if you use g instead of g2).
#Override
protected void paintComponent(Graphics g) { // No need to widen it to public
Graphics2D g2 = (Graphics2D)g;
AffineTransform oldTransform = g2.getTransform();
try {
float zoom = 0.5f; // shrink
// Note that transforms are in reverse order
// because of how matrix multiplications work.
AffineTransform newTransform = new AffineTransform();
// 2nd transform: re-center
newTransform.translate(getWidth() * (1 - zoom) / 2,
getHeight() * (1 - zoom) / 2);
// 1st transform: zoom (relative to upper-left corner)
newTransform.scale(zoom, zoom);
g2.transform(newTransform);
// Draw here
} finally {
// Try-finally is probably not required, but ensures that the transform
// gets restored even if an exception is thrown during drawing.
g2.setTransform(oldTransform);
}
I am trying to draw an Oval with a for loop iterating through a list of coordinates that each contain an x value and y value. Currently, it does not seem to be drawing anything after I start the program. It draws the first time, but when I try drawing when the program is running, it doesn't seem to be drawing.
Here is the code for drawing:
private void render(){
bs = display.getCanvas().getBufferStrategy();
if(bs == null){
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
//Draw Here!
DrawGrid(g);
g.fillOval(100, 100, 10, 10);//this seems to draw
for(int i = 0; i < points.size();i++){//this doesn't draw....
System.out.println(points.get(i));
g.drawString(points.get(i).toString(), points.get(i).x*100-5+100, points.get(i).y-5-300);
g.fillOval(points.get(i).x*100-5+100, points.get(i).y-5-300, 10, 10);
}
//End Drawing!
bs.show();
g.dispose();
}
If you need more details, I am using graphics from java.awt library. Also, I have done this in the past, but I don't know why it isn't working this time.
This part is your issue:
points.get(i).x*100-5+100
Specifically x*100
You are drawing off screen. We can see this by breaking it down:
Lets assume that you have a point of x=28.
Lets do the math on that:
For X = 28 you will have the following calc: (28 * 100) - (5 + 100) = 2695
That X point of 2695 looks very large to me. You would need a 4k screen or ultrawide screen to see it.
The solution:
Have a think about why you are using x*100, and reduce it so that the point fits on your screen. Also, if you have a small y point, then it will be in the negatives (Example: 15-5-300 = -290), and will probably draw above your screen and out of sight.
My teacher is having us write code to draw a logo on the screen using awt, swing, and the graphics class. I decided to draw the google drive symbol, but I am getting stuck on the yellow third.
public class DriveLogo extends JApplet
{
public void init()
{
JRootPane rootPane = this.getRootPane();
rootPane.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
}
public void paint(Graphics g)
{
int num_rect_points = 4;
g.setColor(Color.black);
g.fillRect(0,0,getSize().width, getSize().height);
/*************************************Yellow 1/3**********************************/
//Order of vertices: Left, right, lower-right, lower-left
int p1x1 = 150, p1x2 = 250, p1x3 = 350, p1x4 = 300;
int p1y1 = 25, p1y2 = 25, p1y3 = 280, p1y4 = 280;
int[] poly_1_x = {
p1x1, p1x2, p1x3, p1x4
};
int[] poly_1_y = {
p1y1, p1y2, p1y3, p1y4
};
Polygon yellow = new Polygon(poly_1_x, poly_1_y, num_rect_points);
/*************************************Draw**********************************/
g.setColor(Color.yellow);
g.fillPolygon(yellow);
}
}
This produces the following result:
There should be a yellow rhombus/rectangle slanted to the left. I asked my teacher, and she reviewed my code, but could not isolate the problem, and told me it "should" be working. Should doesn't mean it is however, and this is a rather large grade. Spent most of two class periods and downloaded the project to my home computer to debug, but I just can't seem to figure out what the problem is.
Things I know; the polygon coordinates must be in order, so to draw a rectangle, I cannot list them top-left, bottom-right, bottom-left, top-right, but I can list them top-left, top-right, bottom-right, bottom-left.
Okay, I solved this by experimenting around. For whatever reason, the call to g.fillPolygon(Polygon p) was not working, but when I called g.fillPolygon(poly_1_x, poly_1_y, num_recto_points); it worked properly.
Brief description of Program
Hi guys. I got bored this morning and decided to write a graphing program. Eventually i'll be able to run things like Dijksta's Algorithm on this software.
When anything changes on screen, a call to the repaint method of the JPanel where everything is painted to is made. This is the JPanel paint method:
public void paint(Graphics g)
{
for(Node node : graph.getNodes()){
node.paint(g);
}
for(Link link : graph.getLinks()){
link.paint(g);
}
}
It simply cycles through each element in the lists, and paints them.
The paint method for the node class is:
public void paint(Graphics g)
{
g.setColor(color);
g.drawOval(location.x, location.y, 50, 50);
g.setColor(Color.BLACK);
g.drawString(name, location.x + 20, location.y + 20);
}
And for the link it is:
public void paint(Graphics g)
{
Point p1 = node1.getLocation();
Point p2 = node2.getLocation();
// Grab the two nodes from the link.
g.drawLine(p1.x + 20, p1.y + 20, p2.x + 20, p2.y + 20);
// Draw the line between them.
int midPointX = ((p1.x + p2.x) / 2) + (100 / (p2.x - p1.x));
int midPointY = ((p1.y + p2.y) / 2) + 30;
// Compute the mid point of the line and get it closer to the line.
g.setColor(Color.BLACK);
g.drawString(String.valueOf(weight), midPointX, midPointY);
}
The Problem
The issue I am having arises when I use the JOptionPane class. When I select the option to add a new node, and select where to place it, an inputDialog pops up, asking for the node's name.
The nodes are added fine, for this behaviour occurs:
Is this a common problem; an issue with paint or repaint perhaps?
Nonetheless, here is the code that calls the inputDialog:
Function addNode = functionFac.getInstance(state);
String name = "";
while(!name.matches("[A-Za-z]+")) {
name = JOptionPane.showInputDialog("Please enter the name of the node.", null);
}
addNode.execute(stage, new NodeMessage(arg0.getPoint(), name));
PS: Function is an interface type that I have written.
"Swing programs should override paintComponent() instead of overriding paint()."—Painting in AWT and Swing: The Paint Methods.
"If you do not honor the opaque property you will likely see visual artifacts."—JComponent
See also this Q&A that examines a related issue.