- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
对 Swing 还是比较陌生,但经过几个小时的搜索,我无法在网上找到答案,因此发表了这篇文章(很抱歉,如果已经回答但我忽略了它)。
我在 Swing 应用程序中使用 JFreeChart。一些图表相对较重(180k 数据点)并且 JFreeChart 的 ChartPanel 需要大约 6 秒来执行它的第一个 paintComponent()。
因此,我想在组件绘制时在对话框中显示“请稍候”消息(无需显示 SwingWorker 的进度)。我试图覆盖 paintComponent 方法,但不幸的是该消息从未出现在屏幕上(我猜线程直接进入绘制图表,而没有花时间绘制对话框)。
我的代码是这样的:
public class CustomizedChartPanel extends ChartPanel{
private static final long serialVersionUID = 1L;
private JDialog dialog = null;
boolean isPainted = false;
public CustomizedChartPanel(JFreeChart chart) { super(chart); }
@Override
public void paintComponent(Graphics g) {
//At first paint (which can be lengthy for large charts), show "please wait" message
if (! isPainted){
dialog = new JDialog();
dialog.setUndecorated(true);
JPanel panel = new JPanel();
panel.add(new JLabel("Please wait"));
dialog.add(panel);
dialog.pack();
GuiHelper.centerDialog(dialog); //Custom code to center the dialog on the screen
dialog.setVisible(true);
dialog.repaint();
}
super.paintComponent(g);
if (! isPainted){
isPainted = true;
dialog.dispose();
super.repaint();
}
}
}
非常感谢任何有关如何解决此问题/最佳实践的指示!
谢谢,托马斯
更新:
感谢提示和辩论:非常有帮助。
我开始使用 invokeLater() 实现建议的解决方案,因为我担心 JLayer 解决方案无法工作,因为它也在 EDT 上运行。
不幸的是,当 paintComponent() 被 invokeLater() 调用时,我遇到了一个空指针异常。
我的代码是这样的:
@Override
public void paintComponent(Graphics graph) {
//At first paint (which can be lengthy for large charts), show "please wait" message
if (! isPainted){
isPainted = true;
dialog = new JDialog();
dialog.setUndecorated(true);
JPanel panel = new JPanel();
panel.add(new JLabel("Please wait"));
panel.add(new JLabel("Please wait !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"));
dialog.add(panel);
dialog.pack();
GuiHelper.centerDialog(dialog); //Custom code to center the dialog on the screen
dialog.setVisible(true);
dialog.repaint();
RunnableRepaintCaller r = new RunnableRepaintCaller(this, graph, dialog);
SwingUtilities.invokeLater(r);
}
else super.paintComponent(graph); //NULL POINTER EXCEPTION HERE (invoked by runnable class)
}
可运行类是:
public class RunnableRepaintCaller implements Runnable{
private ChartPanel target;
private Graphics g;
private JDialog dialog;
public RunnableRepaintCaller(ChartPanel target, Graphics g, JDialog dialog){
this.target = target;
this.g = g;
this.dialog = dialog;
}
@Override
public void run() {
System.out.println(g);
target.paintComponent(g);
dialog.dispose();
}
}
同样,任何指针将不胜感激!
托马斯
最佳答案
这是一个示例和/但它使用了 SwingWorker。您应该认真考虑使用它,因为如果操作系统以某种方式使您的框架无效并且 JFreeChart 的加载是在 EDT(事件调度线程)上完成的,那么您的 GUI 将看起来卡住。
它还允许您在处理数据时提供更好的用户反馈。 (抱歉,如果代码有点长,但大部分有趣的代码都在 initUI 和 SwingWorker 中)。
注意:您可以使用 JLayer 而不是对话框(如果您使用 Java 7),但这在我的示例中是不必要的。
代码的灵感来自 http://www.vogella.com/articles/JFreeChart/article.html
/**
* This code was directly taken from: http://www.vogella.com/articles/JFreeChart/article.html
* All credits goes to him for this code.
*
* Thanks to him.
*/
import java.util.List;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.Rotation;
public class PieChart extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initUI();
}
});
}
protected static void initUI() {
// First we create the frame and make it visible
final PieChart demo = new PieChart("Comparison");
demo.setSize(500, 270);
demo.setVisible(true);
// Then we display the dialog on that frame
final JDialog dialog = new JDialog(demo);
dialog.setUndecorated(true);
JPanel panel = new JPanel();
final JLabel label = new JLabel("Please wait...");
panel.add(label);
dialog.add(panel);
dialog.pack();
// Public method to center the dialog after calling pack()
dialog.setLocationRelativeTo(demo);
// allowing the frame and the dialog to be displayed and, later, refreshed
SwingWorker<JFreeChart, String> worker = new SwingWorker<JFreeChart, String>() {
@Override
protected JFreeChart doInBackground() throws Exception {
publish("Loading dataset");
// simulating the loading of the Dataset
try {
System.out.println("Loading dataset");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// This will create the dataset
PieDataset dataset = demo.createDataset();
publish("Loading JFreeChart");
// simulating the loading of the JFreeChart
try {
System.out.println("Loading JFreeChart");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// based on the dataset we create the chart
JFreeChart chart = demo.createChart(dataset, "Which operating system are you using?");
// we put the chart into a panel
return chart;
}
@Override
protected void process(List<String> chunks) {
label.setText(chunks.get(0));
dialog.pack();
dialog.setLocationRelativeTo(demo);
dialog.repaint();
}
@Override
protected void done() {
try {
// Retrieve the created chart and put it in a ChartPanel
ChartPanel chartPanel = new ChartPanel(this.get());
// add it to our frame
demo.setContentPane(chartPanel);
// Dispose the dialog.
dialog.dispose();
// We revalidate to trigger the layout
demo.revalidate();
// Repaint, just to be sure
demo.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
};
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
worker.execute();
}
});
dialog.setVisible(true);
}
public PieChart(String applicationTitle) {
super(applicationTitle);
}
/** * Creates a sample dataset */
private PieDataset createDataset() {
DefaultPieDataset result = new DefaultPieDataset();
result.setValue("Linux", 29);
result.setValue("Mac", 20);
result.setValue("Windows", 51);
return result;
}
/** * Creates a chart */
private JFreeChart createChart(PieDataset dataset, String title) {
JFreeChart chart = ChartFactory.createPieChart3D(title, // chart title
dataset, // data
true, // include legend
true, false);
PiePlot3D plot = (PiePlot3D) chart.getPlot();
plot.setStartAngle(290);
plot.setDirection(Rotation.CLOCKWISE);
plot.setForegroundAlpha(0.5f);
return chart;
}
}
关于java - 如何在组件绘制时创建 "please wait"Swing 对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11746891/
我有一个删除按钮,单击该按钮时我希望弹出一个对话框,然后单击“确定”它应该执行 Ajax 调用,否则不应该执行任何操作。这是代码 $('.comment-delete').click(function
public void exitGame() { //pop up dialogue Platform.exit(); } 我已经尝试了很多我在互联网上看到的不同的东西,但我什么都做不了。我所
我有一个典型的素面对话框,效果很好,但是当有人在对话框外单击时,我找不到任何关闭它的选项。我看到了一些jquery示例,我想我可以将其改编为primefaces对话框,但首先要确保还没有解决方案? 谢
我试图让 jquery 对话框在单击按钮时启动,但似乎不起作用。任何帮助将不胜感激: $('#wrapper').dialog({ autoOpen: false,
我试图单独更改标题栏颜色。所以我使用了 .ui-dialog-titlebar ,但它不起作用,所以我尝试使用 ui-widght-header ,它也反射(reflect)到数据表..请告知。 //
我的页面上有 div(box),我正在使用此脚本将 div 显示为对话框。在该 div 内,我有一个超链接,单击该超链接时,我想淡出对话框并关闭。对话框的内容淡出,但对话框的边框保持不变。如果我将 $
我当前有一个对话框,其内容有两个输入(这两个输入使用 .datepicker())。当我打开对话框时,第一个输入成为焦点,并且第一个日期选择器自动出现。我尝试隐藏 div 并模糊输入,但这会导致日期选
我想即时创建一个 jQuery 对话框。我正在使用这个: var newDiv = $(document.createElement('div')); $(newDiv).html('hello th
child: RaisedButton( color: const Color(0xFF5867DD), onPressed: (){ updateProfilePic();
我有下面的 jquery 代码,我已根据我的要求对其进行了自定义,但存在一些问题。首先,用户单击“单击此处”,不会显示对话框。当用户单击“关闭”时,对话框不会消失。非常感谢您提供的所有帮助。
如何创建一个对话框,该对话框的顶部有一个文本,其下方有一个空白区域,用户可以在其中键入内容,在右侧下方有一个 OKAY 按钮,当您单击该按钮时,对话框消失? 像这样: 最佳答案 String inpu
这是一个简单得多的问题。 private static AplotBaseDialog dlg; public Object execute(final ExecutionEvent event) t
我正在为我的应用程序开发小部件。应该有一些小部件可以实现相同的功能,唯一的区别在于它们的布局(主题/外观) 我会创建一个对话框或屏幕,用户可以在其中选择他喜欢的小部件。当我选择它们时,我在很多小部件中
我有 jQuery 对话框窗口,在某些操作中我有一个加载的 blockUI 插件。 我面临的问题是,即使 AJAX 图像仍在显示,我仍然能够在执行 ajax 操作时执行操作。 另一方面,JSP 页面在
我非常熟悉将 jQuery 对话框 div 设置为可见后将其附加到表单元素的技巧。我已经在 .NET 中这样做了一百次左右,而且效果很好!然而,我正在尝试在 Coldfusion 网站上执行此操作,这
我想使用jquery对话框来收集用户信息(例如用户名)。我如何使用 Jquery 做到这一点并将数据收集到 Javascript 变量中? 这是我迄今为止的尝试: // Dialog here, ho
如何设置 jquery 对话框按钮的工具提示?请参阅下面的内容...这里没有 id 或样式类。 jQuery("#dialog-form").dialog ({ autoOpen: false,
我有调用对话框的 JS 函数 function SomeFunction { $('#editformdialog').dialog('open'); } 这显然已经简化了。但是,我得到 a is u
我正在使用 jquery 模式对话框来显示部分 View 中的数据表。在部分 View 中,我有一些脚本,用于将 HTML 表更改为 jquery DataTables。因此,我需要确保表格在对话框中
我正在尝试添加透明的 JQuery 对话框。但我遇到了两个问题: 文本“Hello”的背景不会变得透明 删除标题栏后,我无法再拖动对话框 这些评论是我迄今为止尝试过的。 //Create ne
我是一名优秀的程序员,十分优秀!