摘要:我目前正在做一个模拟出租车的小程序实验室练习,它必须显示速度,燃料,票价和行驶距离,以及出租车是否被占用或空置。它具有为用户提供交互的按钮。 问题:我用一个线程来表示票价、距离和燃料,另一个线程用于选取框,但为什么我的选取框一直在闪烁?
问问题
1280 次
1 回答
3
没有代码,这真的是任何人的猜测,但无论如何我都会尝试一下。我的猜测是您直接在 JApplet 的paint(...)
方法中绘图,从而失去了 Swing 双缓冲的所有可能收益。如果是这样,那么更改它并绘制paintComponent(...)
JApplet 正在显示的 JPanel 的方法。
如果这没有帮助,那么考虑给我们足够的信息,这样我们就不必猜测了。您可能想向我们说明您是如何处理线程的,并向我们保证您会小心遵守 Swing 线程规则并仅在事件线程上更新 Swing 组件。
编辑
您的代码:
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.JApplet;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.border.Border;
/**
*
* @author IC
*/
public class taxiCab extends JApplet implements ActionListener {
private JTextField speed, distance, fare, fuel, ov, full, tf, tf_fuel, tf_speed;
private JButton butt, start, butt_pass, butt_sUp, butt_sDown, butt_refuel;
private JLabel label;
private JPanel main, north, south, south_left, south_right, center, center_content, north_speed, north_distance, north_fuel, north_fare;
private Container contain;
private int speedVal, distanceVal, passval, thread_sleep, status_width, fuel_width;
private float fuelVal, fareVal;
private Graphics g;
private String status;
private Font font2 = new Font("Kozuka Gothic Pro B", Font.BOLD, 60);
private Border border2 = BorderFactory.createLineBorder(Color.black, 3);
private Border border1 = BorderFactory.createLineBorder(Color.black, 1);
private final int width_ = 500;
private final int height_ = 300;
Thread thread1 = new trd1();
Thread thread2 = new trd2();
/**
* Initialization method that will be called after the applet is loaded into
* the browser.
*/
public void init() {
setSize(width_,height_);
status = new String();
status = "VACANT";
status_width = -330;
Border border3 = BorderFactory.createLineBorder(Color.black, 5);
thread1 = new trd1();
thread2.start();
thread2.suspend();
contain = new Container();
contain = getContentPane();
main = new JPanel(new BorderLayout());
north = new JPanel(new GridLayout(2,2));
north.setBackground(Color.blue);
north_speed = new JPanel();
tf_speed = new JTextField(10);
tf_speed.setBorder(border1);
tf_speed.setText("Speed");
tf_speed.setHorizontalAlignment(JTextField.CENTER);
tf_speed.setBackground(Color.CYAN);
tf_speed.setEditable(false);
speed = new JTextField(10);
speed.setBorder(border1);
speed.setEditable(false);
speed.setText("-");
speed.setHorizontalAlignment(JTextField.CENTER);
north_speed.add(tf_speed);
north_speed.add(speed);
north_distance = new JPanel();
tf = new JTextField(10);
tf.setBorder(border1);
tf.setText("Distance");
tf.setHorizontalAlignment(JTextField.CENTER);
tf.setBackground(Color.CYAN);
tf.setEditable(false);
distance = new JTextField(10);
distance.setBorder(border1);
distance.setEditable(false);
distance.setText("-");//<----------------------------------distance
distance.setHorizontalAlignment(JTextField.CENTER);
north_distance.add(tf);
north_distance.add(distance);
north_fuel = new JPanel();
tf_fuel = new JTextField(10);
tf_fuel.setBorder(border1);
tf_fuel.setText("Fuel");
tf_fuel.setHorizontalAlignment(JTextField.CENTER);
tf_fuel.setBackground(Color.CYAN);
tf_fuel.setEditable(false);
fuel = new JTextField(10);
fuel.setBorder(border1);
fuel.setEditable(false);
fuel.setText("-");
fuel.setHorizontalAlignment(JTextField.CENTER);
north_fuel.add(tf_fuel);
north_fuel.add(fuel);
north_fare = new JPanel();
tf = new JTextField(10);
tf.setBorder(border1);
tf.setText("Fare");
tf.setHorizontalAlignment(JTextField.CENTER);
tf.setBackground(Color.CYAN);
tf.setEditable(false);
fare = new JTextField(10);
fare.setBorder(border1);
fare.setEditable(false);
fare.setText("-");
fare.setHorizontalAlignment(JTextField.CENTER);
north_fare.add(tf);
north_fare.add(fare);
north.add(north_speed);
north.add(north_distance);
north.add(north_fuel);
north.add(north_fare);
center = new JPanel(new BorderLayout(3,3));
center_content = new JPanel(new GridLayout(2,1,0,15));
ov = new JTextField(20);
ov.setText("");
ov.setBackground(Color.yellow);
ov.setEditable(false);
ov.setBorder(border2);
full = new JTextField(20);
full.setHorizontalAlignment(JTextField.CENTER);
full.setText("FUELMeter");
full.setIgnoreRepaint(true);
full.setFont(font2);
full.setBorder(border2);
center_content.add(ov);
center_content.add(full);
center.add(center_content, "Center");
center_content.setBackground(Color.yellow);
label = new JLabel(" ");
center.add(label, "North");
label = new JLabel(" ");
center.add(label, "West");
label = new JLabel(" ");
center.add(label, "South");
label = new JLabel(" ");
center.add(label, "East");
south = new JPanel(new BorderLayout());
south_left = new JPanel(new GridLayout(2,1));
butt_sUp = new JButton("Speed Up");
butt_sUp.setBorder(border1);
butt_sUp.addActionListener(this);
butt_sUp.setEnabled(false);
south_left.add(butt_sUp);
butt_sDown = new JButton("Speed Down");
butt_sDown.setBorder(border1);
butt_sDown.addActionListener(this);
butt_sDown.setEnabled(false);
south_left.add(butt_sDown);
south_right = new JPanel(new GridLayout(2,1));
butt_pass = new JButton("Passenger In");
butt_pass.setBorder(border1);
butt_pass.addActionListener(this);
butt_pass.setEnabled(false);
south_right.add(butt_pass);
butt_refuel = new JButton("Refuel");
butt_refuel.setBorder(border1);
butt_refuel.addActionListener(this);
butt_refuel.setEnabled(false);
south_right.add(butt_refuel);
butt = new JButton("Start");
butt.setBorder(border1);
butt.addActionListener(this);
south.add(butt, "Center");
south.add(south_left, "West");
south.add(south_right, "East");
north.setBorder(border1);
center.setBorder(border1);
south.setBorder(border1);
center.setBackground(Color.yellow);
main.add(north, "North");
main.add(center, "Center");
main.add(south, "South");
main.setBorder(border1);
//main.setIgnoreRepaint(true);
contain.add(main);
contain.setVisible(true);
//contain.setIgnoreRepaint(true);
}
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.black);
g.setFont(font2);
g.drawString(status, status_width, 140);
g.setColor(Color.yellow);
g.fillRect(2,82,12,70);
g.fillRect(getWidth()-14,82,12,70);
g.setColor(Color.black);
g.fillRect(0,82,2,70);
g.setColor(Color.GREEN);
g.fillRect(17,(getHeight()/2)+20,fuel_width,getHeight()-(83+(getHeight()/2)));
main.setBorder(border1);
}
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand() == "Start"){
butt.setLabel("Stop");
butt_pass.setEnabled(true);
fuelVal = 50.00f;
distanceVal = 0;
fareVal = 40.00f;
speedVal = 0;
fuel.setText(String.valueOf(fuelVal) + " L");
distance.setText(String.valueOf(distanceVal) + " km");
fare.setText("Php " + String.valueOf(fareVal));
speed.setText(String.valueOf(speedVal) + " kph");
thread1 = new trd1();
thread1.start();
thread2 = new trd2();
thread2.start();
//BufferedWriter bw;<-----------------------------------------------
}
else if(e.getActionCommand() == "Stop"){
butt.setLabel("Start");
butt_pass.setEnabled(false);
butt_sUp.setEnabled(false);
butt_sDown.setEnabled(false);
butt_refuel.setEnabled(false);
butt_pass.setLabel("Passenger In");
thread1.stop();
}
else if(e.getActionCommand() == "Speed Up"){
if(speedVal == 0){
speedVal+=25;
speed.setText(String.valueOf(speedVal) + " kph");
butt_sDown.setEnabled(true);
tf_speed.setText("Speed");
thread1 = new trd1();
thread1.start();
}
else if(speedVal == 275){
speedVal+=25;
speed.setText(String.valueOf(speedVal) + " kph");
//butt_sUp.setEnabled(false);
tf_speed.setText("MAX SPEED");
}
else{
speedVal+=25;
speed.setText(String.valueOf(speedVal) + " kph");
}
}
else if(e.getActionCommand() == "Speed Down"){
repaint();
if(speedVal==25){
speedVal-=25;
speed.setText(String.valueOf(speedVal) + " kph");
tf_speed.setText("S T O P P E D");
butt_sDown.setEnabled(false);
}
else if(speedVal == 300){
speedVal-=25;
speed.setText(String.valueOf(speedVal) + " kph");
tf_speed.setText("Speed");
butt_sUp.setEnabled(true);
}
else{
speedVal-=25;
speed.setText(String.valueOf(speedVal) + " kph");
}
}
else if(e.getActionCommand() == "Passenger In"){
butt_pass.setLabel("Passenger Out");
fareVal = 40.0f;
fare.setText("Php " + String.valueOf(fareVal));
butt_sUp.setEnabled(true);
butt_sDown.setEnabled(true);
butt_refuel.setEnabled(true);
speedVal = 25;
speed.setText(String.valueOf(speedVal) + " kph");
status = "OCCUPIED";
thread1 = new trd1();
thread1.start();
}
else if(e.getActionCommand() == "Passenger Out"){
status = "VACANT";
butt_pass.setLabel("Passenger In");
thread1.stop();
}
else if(e.getActionCommand() == "Refuel"){
if(fuelVal == 0.0f){
fuelVal = 50.00f;
fuel.setText(String.valueOf(fuelVal));
tf_fuel.setBackground(Color.cyan);
tf_fuel.setText("Fuel");
fuel_width = (int)((getWidth()-34)*fuelVal/50f);
thread1 = new trd1();
thread1.start();
}
else{
fuelVal = 50.00f;
fuel.setText(String.valueOf(fuelVal) + " L");
}
}
}
public class trd1 extends Thread implements Runnable {
public void run(){
if(fuelVal>0.00f || speedVal>0){
for(;;){
try {
Thread.sleep(50000/speedVal);
if(fuelVal == 0.00f || speedVal == 0)
thread1.stop();
distanceVal++;
fareVal += 1.00;
fuelVal -=.25f;
fuel_width = (int)((getWidth()-34)*fuelVal/50f);
repaint();
distance.setText(String.valueOf(distanceVal)+" km");
fuel.setText(String.valueOf(fuelVal)+" L");
fare.setText("P " + String.valueOf(fareVal));
} catch (InterruptedException e) {
}
}
}
}
}
public class trd2 extends Thread implements Runnable {
//tf_fuel = new JTextField(15);
public void run(){
for(int b = 0;;b++){
try {
Thread.sleep(10);
status_width +=1;
if(status_width == getWidth())
status_width = -330;
repaint();
if(fuelVal == 0.0f){
if(b%2==0){
tf_fuel.setBackground(Color.red);
tf_fuel.setText("R E F U E L");
}
else{
tf_fuel.setBackground(Color.cyan);
tf_fuel.setText("R E F U E L");
}
}
} catch (InterruptedException e) {
}
}
}
}
}
是的,我猜对了:你直接在 JApplet 中绘画。正如我最初所说,不要那样做。实际上,学习正确执行此操作的最佳选择是阅读教程:
您的代码中还有很多其他错误,其中一些很重要,包括使用 == 比较字符串而不是equals(...)
orequalsIgnoreCase(...)
方法,以及尝试Thread#stop()
直接调用。永远不要那样做。也不要在paint 或paintComponent 中设置组件的边框。此外,您正在后台线程内和 Swing 事件线程之外设置组件的文本和背景颜色——这两个可能导致间歇性和难以调试线程错误的原因。您只想在 Swing 事件线程上做这些事情。
于 2012-07-22T01:42:07.973 回答