该程序为条形图绘制了一堆矩形。我知道吧类的工作非常好,因为我在添加图表面板类之前已经完成了它。我正在直接画到框架而不是图形面板。我认为我的set可见方法被调用的方式存在问题,因为之前曾向我指出过。我试着调查一下但是在玩完并阅读文档之后我没有运气。
import java.awt.Color;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.concurrent.Semaphore;
@SuppressWarnings("serial")
public class GraphPanel extends JPanel {
private ArrayList<Bar> graphBars;
private int nBars;
public GraphPanel(int nBars, JFrame mainFrame) {
this.setSize(400, 400);
this.graphBars = new ArrayList<Bar>(nBars);
this.nBars = nBars;
this.initBars(mainFrame.getWidth());
for(Bar b: this.graphBars) {
this.add(b);
}
}
private void initBars(int frameW) {
Random random = new Random();
float hue;
Color color;
int barPadding = frameW/this.nBars;
for(int i = 0; i < this.nBars; i++) {
hue = random.nextFloat();
color = Color.getHSBColor(hue, 0.9f, 1.0f);
this.graphBars.add(new Bar(i*barPadding + 30, 350, color));
}
}
public ArrayList<Bar> getBarList() {
return this.graphBars;
}
}
@SuppressWarnings("serial")
public class Bar extends JPanel implements Runnable {
int height = 0;
Color barColor;
Rectangle bar;
private final int WIDTH = 20;
Thread bartender;
private Semaphore s;
public Bar(int x, int y, Color barColor) {
this.barColor= barColor;
this.bar = new Rectangle(x, y, this.WIDTH, this.height);
this.bartender= new Thread(this);
this.s = new Semaphore(1);
}
public boolean setNewHeight(int h) {
try {
this.s.acquire();
this.height = h;
this.s.release();
return true;
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
@SuppressWarnings("deprecation")
public void update() {
if (this.bar.height < this.height) {
bar.reshape(this.bar.x, --this.bar.y, this.bar.width, ++this.bar.height);
} else {
bar.reshape(this.bar.x, ++this.bar.y, this.bar.width, --this.bar.height);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(this.barColor);
g2d.fill(this.bar);
}
@SuppressWarnings("deprecation")
public void callBarTender() {
this.bartender.resume();
}
@SuppressWarnings("deprecation")
@Override
public void run() {
System.out.println("sdf");
while(true) {
if (this.bar.height < this.height) {
for(int i = this.bar.height; i<this.height; i++ ) {
try {
update();
repaint();
Thread.sleep(15);
} catch(Exception e) {
System.out.println(e);
}
}
} else if (this.height < this.bar.height) {
for(int i = this.bar.height; i>this.height; i-- ) {
try {
update();
repaint();
Thread.sleep(15);
} catch(Exception e) {
System.out.println(e);
}
}
}
this.bartender.suspend();
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphPanel gPane = new GraphPanel(3, frame);
frame.add(gPane);
gPane.getBarList().get(0).setVisible(true);
gPane.getBarList().get(1).setVisible(true);
gPane.getBarList().get(2).setVisible(true);
gPane.setVisible(true);
frame.setVisible(true);
gPane.getBarList().get(0).setNewHeight(100);
gPane.getBarList().get(1).setNewHeight(100);
gPane.getBarList().get(2).setNewHeight(100);
gPane.getBarList().get(0).bartender.start();
gPane.getBarList().get(1).bartender.start();
gPane.getBarList().get(2).bartender.start();
}
答案 0 :(得分:4)
getPreferredSize
的{{1}}以确保它们的布局正确GraphPanel
类的x / y位置无关紧要,因为这会导致Bar
在Rectangle
窗格的可见上下文之外绘制。绘画是在组件的上下文中完成的(0x0是组件的顶部/左角)Bar
或您使用它的方式实际上会导致问题。在组件铺设或涂漆之前,不可能确切知道组件的大小。Rectangle
和resume
被弃用,这可能会导致“#34;奇怪的”#34; (和精彩)问题suspend
可能更像是......
Thread