- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的程序通过两个新的视觉演示直观地演示了众所周知的 QuickSort 算法的顺序版本:(I) 使用低级 Thread API 和 SwingUtilities 实现的 QuickSort 并行版本,以及 (II) 使用 SwingWorker API 实现的 QuickSort 并行版本。
我正在尝试有一个工具可以在成功运行后重新启动程序。目前,排序操作开始时按钮被禁用,这是正确的,但它们永远不会重新启用,所以我想知道是否有办法在成功运行后启用所有按钮?部分代码如下:
// http://www.java2s.com/Code/Java/Collections-Data-Structure/Animationforquicksort.htm
// http://www.sorting-algorithms.com/quick-sort
import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.util.*;
import javax.swing.*;
import java.util.concurrent.atomic.*;
public class QuickSortVisualizer implements Runnable {
static int LENGTH = 32;
static int LEFT = 500;
static int RIGHT = 500;
static int SWAP = 1000;
int[] Values;
AtomicInteger WorkerThreads = new AtomicInteger();
public static void main(String[] args) {
try {
if (args.length == 0) {
LENGTH = 32;
LEFT = 500;
RIGHT = 500;
SWAP = 1000;
} else if (args.length == 4) {
//dw about this
} else {
throw new Exception("incorrect command-line argument count");
}
System.err.format("... LENGTH=%d LEFT=%d RIGHT=%d SWAP=%d%n", LENGTH, LEFT, RIGHT, SWAP);
SwingUtilities.invokeAndWait(new QuickSortVisualizer());
System.err.format("... GUI started%n");
} catch (Exception ex) {
System.err.format("*** %s%n", ex.getMessage());
}
}
JButton BoredButton;
JButton WorkerButtonSequential;
JButton WorkerButtonThreads;
JButton WorkerButtonSwingWorkers;
SorterPanel MySortPanel;
JLabel StatusBar;
public void run() {
JFrame frame = new JFrame();
frame.setTitle("My Quick Sort Visualizer");
Font font = new Font("Monospaced", Font.BOLD, 18);
BoredButton = new JButton("I am bored");
BoredButton.setFont(font);
BoredButton.setPreferredSize(new Dimension(180, 30));
BoredButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
BoredButton_Click();
}
});
WorkerButtonSequential = new JButton("QS Sequential");
WorkerButtonSequential.setFont(font);
WorkerButtonSequential.setPreferredSize(new Dimension(185, 30));
WorkerButtonSequential.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
WorkerButtonSequential_Click();
}
});
WorkerButtonThreads = new JButton("QS Threads");
WorkerButtonThreads.setFont(font);
WorkerButtonThreads.setPreferredSize(new Dimension(185, 30));
WorkerButtonThreads.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
WorkerButtonThreads_Click();
}
});
WorkerButtonSwingWorkers = new JButton("QS SwingWorkers");
WorkerButtonSwingWorkers.setFont(font);
WorkerButtonSwingWorkers.setPreferredSize(new Dimension(200, 30));
WorkerButtonSwingWorkers.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
WorkerButtonSwingWorkers_Click();
}
});
JPanel strip = new JPanel(new FlowLayout(FlowLayout.CENTER));
strip.add(BoredButton);
strip.add(WorkerButtonSequential);
strip.add(WorkerButtonThreads);
strip.add(WorkerButtonSwingWorkers);
frame.getContentPane().add(strip, BorderLayout.NORTH);
StatusBar = new JLabel();
StatusBar.setFont(font);
StatusBar.setPreferredSize(new Dimension(800, 20));
frame.getContentPane().add(StatusBar, BorderLayout.SOUTH);
MySortPanel = new SorterPanel();
frame.getContentPane().add(MySortPanel, BorderLayout.CENTER);
frame.getRootPane().setDefaultButton(BoredButton);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 400);
frame.setResizable(true);
frame.setVisible(true);
}
public void BoredButton_Click() {
String text = Calendar.getInstance().getTime().toString();
StatusBar.setText(text);
System.err.format("... now %s%n", text);
}
public void WorkerButtonSequential_Click() {
WorkerButtonSequential.setEnabled(false);
WorkerButtonThreads.setEnabled(false);
WorkerButtonSwingWorkers.setEnabled(false);
System.err.format("... sequential%n");
QSSequential();
}
public void WorkerButtonThreads_Click() {
WorkerButtonSequential.setEnabled(false);
WorkerButtonThreads.setEnabled(false);
WorkerButtonSwingWorkers.setEnabled(false);
int processors = Runtime.getRuntime().availableProcessors();
int threshold = processors * 2;
System.err.format("... parallel threads: processors=%d threshold=%d%n", processors, threshold);
QSThreads(threshold);
}
public void WorkerButtonSwingWorkers_Click() {
WorkerButtonSequential.setEnabled(false);
WorkerButtonThreads.setEnabled(false);
WorkerButtonSwingWorkers.setEnabled(false);
int processors = Runtime.getRuntime().availableProcessors();
int threshold = processors * 2;
System.err.format("... parallel swingworkers: processors=%d threshold=%d%n", processors, threshold);
QSSwingWorkers(threshold);
}
void QSInit() {
Values = new int[LENGTH];
for (int i = 0; i < Values.length; i++) {
Values[i] = (int)Math.round(Math.random() * (MySortPanel.getHeight()-10));
}
print("... initial values");
MySortPanel.setValues(Values);
}
void QSSequential() {
QSInit();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
QuickSortSequential qss = new QuickSortSequential(Values, 0, Values.length - 1, MySortPanel);
System.err.format("... started%n");
qss.run();
DoneAll();
}
});
}
void QSThreads(int threshold) {
QSInit();
QuickSortThread qst = new QuickSortThread(Values, 0, Values.length - 1, threshold, MySortPanel);
WorkerThreads.set(0);
incWorkerThreads();
System.err.format("... started%n");
qst.start();
}
void QSSwingWorkers(int threshold) {
QSInit();
QuickSortWorker qsw = new QuickSortWorker(Values, 0, Values.length - 1, threshold, MySortPanel);
WorkerThreads.set(0);
incWorkerThreads();
System.err.format("... started%n");
qsw.execute();
}
void print(String caption) {
System.err.format("%s%n", caption);
for (int i=0; i<Values.length; i++) {
System.err.format(" %d:%d", i, Values[i]);
}
System.err.format("%n");
}
void incWorkerThreads() {
int w = WorkerThreads.incrementAndGet();
System.err.format("... workers=%d%n", w);
}
void decWorkerThreads() {
int w = WorkerThreads.decrementAndGet();
System.err.format("... workers=%d%n", w);
if (w <= 0) DoneAll();
}
void DoneAll() {
print("... sorted values");
WorkerButtonSequential.setEnabled(true);
WorkerButtonThreads.setEnabled(true);
WorkerButtonSwingWorkers.setEnabled(true);
System.err.format("%n");
}
// === SorterPanel
/* colour codes
pivot : YELLOW
left item : GREEN
right item : BLUE
left item just before swap : PINK
right item just before swap : PINK
left item just after swap : RED
right item just after swap : RED
*/
class SorterPanel extends JComponent {
int[] Values;
int width;
Graphics2D g2;
Color pen;
Color back;
public void setValues(int[] Values) {
this.Values = Values;
width = super.getWidth() / Values.length;
repaint();
}
@Override
public void paintComponent(Graphics g) {
if (Values == null) return;
g2 = (Graphics2D) g;
pen = Color.BLACK; // g2.getColor();
back = g2.getBackground();
for (int i = 0; i < Values.length; i++) {
g2.draw(new Rectangle2D.Double(width*i+1, 0, width-2, Values[i]));
}
}
public void mark(int i, int value, Color m) {
g2 = (Graphics2D) super.getGraphics();
pen = g2.getColor();
g2.setColor(m);
//g2.fill(new Rectangle2D.Double(width*i+2, 1, width-4, Values[i]-2));
g2.fill(new Rectangle2D.Double(width*i+2, 1, width-4, value-2));
g2.setColor(pen);
}
public void unmark(final int i, final int value) {
mark(i, value, back);
}
public void erase(int i, int value) {
g2 = (Graphics2D) super.getGraphics();
//g2.clearRect(width*i+1, 0, width-1, Values[i]+1);
g2.clearRect(width*i+1, 0, width-1, value+1);
}
public void redraw(int i, int value) {
g2 = (Graphics2D) super.getGraphics();
//g2.draw(new Rectangle2D.Double(width*i+1, 0, width-2, Values[i]));
g2.draw(new Rectangle2D.Double(width*i+1, 0, width-2, value));
mark(i, value, back);
}
}
// === QuickSort Sequential
class QuickSortSequential implements Runnable {
int[] array;
int left;
int right;
// === GUI stuff
SorterPanel sortpan;
void publish(Runnable gui_update) {
gui_update.run();
}
void mark(final int idx, final Color color) {
final int value = array[idx];
publish(new Runnable() {
public void run() {
sortpan.mark(idx, value, color);
}
});
}
void unmark(final int idx) {
final int value = array[idx];
publish(new Runnable() {
public void run() {
sortpan.unmark(idx, value);
}
});
}
void erase(final int idx) {
final int value = array[idx];
publish(new Runnable() {
public void run() {
sortpan.erase(idx, value);
}
});
}
void redraw(final int idx) {
final int value = array[idx];
publish(new Runnable() {
public void run() {
sortpan.redraw(idx, value);
}
});
}
void sleep(int period) {
try {
Thread.sleep(period);
} catch (Exception ex) {
System.err.format("%s%n", ex.getMessage());
}
}
// === stuff
public QuickSortSequential(final int array[], final int left, final int right, final SorterPanel sortpan) {
this.array = array;
this.left = left;
this.right = right;
this.sortpan = sortpan;
}
public void run() {
QuickSort();
}
// === QuickSort stuff
void QuickSort() {
if (left >= right) return;
final int pivot = Partition();
if (pivot < 0) return;
QuickSortSequential lquick = new QuickSortSequential(array, left, pivot-1, sortpan);
QuickSortSequential rquick = new QuickSortSequential(array, pivot, right, sortpan);
lquick.run();
rquick.run();
}
int Partition() {
int leftIdx = left;
int rightIdx = right;
int pivotIdx = (left + right) / 2;
final int pivot = array[pivotIdx];
while (true) {
if (leftIdx > rightIdx) break;
mark(pivotIdx, Color.YELLOW);
mark(leftIdx, Color.GREEN);
mark(rightIdx, Color.BLUE);
sleep(LEFT);
while (true) {
if (array[leftIdx] >= pivot) break;
else {
unmark(leftIdx);
leftIdx += 1;
mark(pivotIdx, Color.YELLOW);
mark(leftIdx, Color.GREEN);
sleep(LEFT);
}
}
while (true) {
if (pivot >= array[rightIdx]) break;
else {
unmark(rightIdx);
rightIdx -= 1;
mark(pivotIdx, Color.YELLOW);
mark(rightIdx, Color.BLUE);
sleep(RIGHT);
}
}
unmark(pivotIdx);
unmark(leftIdx);
unmark(rightIdx);
if (leftIdx <= rightIdx) {
if (leftIdx < rightIdx) {
mark(pivotIdx, Color.YELLOW);
mark(leftIdx, Color.PINK);
mark(rightIdx, Color.PINK);
sleep(SWAP);
erase(leftIdx);
erase(rightIdx);
int temp = array[rightIdx];
array[rightIdx] = array[leftIdx];
array[leftIdx] = temp;
if (pivotIdx == leftIdx) pivotIdx = rightIdx;
else if (pivotIdx == rightIdx) pivotIdx = leftIdx;
redraw(leftIdx);
redraw(rightIdx);
mark(pivotIdx, Color.YELLOW);
mark(leftIdx, Color.RED);
mark(rightIdx, Color.RED);
sleep(SWAP);
}
unmark(pivotIdx);
unmark(leftIdx);
unmark(rightIdx);
leftIdx += 1;
rightIdx -= 1;
}
}
return leftIdx;
}
}
// === QuickSort with Threads
class QuickSortThread extends Thread {
int[] array;
int left;
int right;
int threshold;
// === GUI stuff
SorterPanel sortpan;
// === Thread etc stuff
public QuickSortThread(final int array[], final int left, final int right, final int threshold, final SorterPanel sortpan) {
this.array = array;
this.left = left;
this.right = right;
this.sortpan = sortpan;
this.threshold = threshold;
}
@Override
public void run() {
decWorkerThreads();
}
}
// === QuickSort with SwingWorkers
class QuickSortWorker extends SwingWorker<Boolean, Runnable> {
int[] array;
int left;
int right;
int threshold;
// === GUI stuff
SorterPanel sortpan;
// === SwingWorker stuff
public QuickSortWorker(final int array[], final int left, final int right, final int threshold, final SorterPanel sortpan) {
this.array = array;
this.left = left;
this.right = right;
this.threshold = threshold;
this.sortpan = sortpan;
}
@Override
public Boolean doInBackground() {
return true;
}
@Override
public void process(java.util.List<Runnable> gui_updates) {
}
@Override
public void done() {
decWorkerThreads();
}
}
}
最佳答案
不是直接回答你的问题,但我看到三个区域,我认为你的代码遗漏了
实现SwingWorker#cancel() ,用于重新启动进程
实现PropertyChangeListene r 用于收听更改从 SwingWorker
关于java - 线程和按钮 : How to restart the program after its finished running,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7721233/
我认为这个问题说明了一切,但我有一个使用 .net 安装工具包的应用程序(在 vs.2005 中),并且用户问我是否可以将它安装在 c:\Program Files\ProgramName 而不是C:
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我是 Stephen Wolfram 的忠实粉丝,但他绝对是一个不怕自吹自擂的人。在许多引用资料中,他将 Mathematica 颂扬为一种不同的符号编程范式。我不是 Mathematica 用户。
我现在正在使用 Squeak4.1 学习 SmallTalk。我使用 Squeak by Example 作为教程,在这里我反驳了一个 delema,“Morphic 是由...开发的,用于自编程语言
Wikipedia有话要说: Total functional programming (also known as strong functional programming, to be cont
在阅读 Paul Graham's Essays 时, 我对 Lisp 越来越好奇了。 在this article ,他提到最强大的功能之一是您可以编写可以编写其他程序的程序。 我无法在他的网站或其他
我知道 functional programming 有几个定义。 .我认为这是一个模糊的类别。我个人的定义是接近' referential transparency '。 这个问题不是“函数式编程的
我注意到许多顶尖大学都开设了类(class),在这些类(class)中,学生将学习与计算机图形学相关的 CS 专业科目。可悲的是,这是我的大学没有提供的东西,我真的很想在 future 几年的某个时候
我正在安装100%托管代码的.NET(C#)应用程序。安装程序(InnoSetup)始终希望将应用程序安装到Vista x64中的“Program Files(x86)”文件夹中,我认为这是因为安装程
假设在 C 中,我们有以下结构: struct MyData { char key1[20]; long key2; ... /* some data */ }; 本质上,除
这个问题已经有答案了: When should I use ampersand with scanf() (3 个回答) 已关闭 6 年前。 所以我在python3中有这个“程序”,它添加了3个字符串
我编写了一个包含 self 更新程序的 Java 应用程序。自更新程序从 Web 服务器加载新的程序版本并替换应用程序文件。如果安装了应用程序,这将完美地工作,例如在用户主目录中,如果它安装在 C:\
注意:标记为社区维基。 是否有一个很好的分析为什么可视化编程语言仍然没有起飞?这些天我们仍在 80x25 文本窗口中“线性”编码;而我们表示的概念(数据结构、算法)似乎可以更直观地表示出来。 最佳答案
我一直在阅读Code Complete 2 .由于我不是以英语为母语的人,因此我需要一些时间才能理解某些陈述。我希望你描述作者在他的书中所做的这两个陈述之间的区别: You should progra
我在为我的 tomcat 设置 CLASSPATH 时遇到了这个问题。我需要在 tomcat 的 CLASSPATH 中引用我的 2 个安装。其中一个位于 C:\Program Files\Postg
这个问题已经有答案了: How can I lock a file using java (if possible) (8 个回答) 已关闭 6 年前。 我有 2-3 个程序可以修改文件,但如果有一个
我 checkout Reading stdout from one program in another program却没有找到我要找的答案 我是 Linux 的新手,我正在使用 Python 中
我有一个程序可以打印出通过或失败。我想检测卡在那里的程序并回显“超时” 我写了这样一个脚本: #!/bin/bash echo -n 'test' && timeout 5 ./mytest | gr
我非常清楚函数式编程技术和命令式编程技术之间的区别。但是现在有一种普遍的趋势是谈论“函数式语言”,这确实让我感到困惑。 当然,像 Haskell 这样的一些语言比 C 等其他语言更欢迎函数式编程。但即
请求:每个进程需要计算自己的组到所有点的距离。我的代码如下: #include stdio.h #include stdlib.h #include math.h #include string.h
我是一名优秀的程序员,十分优秀!