当前位置: 首页 > 知识库问答 >
问题:

JFreechart程序正在运行,但未显示窗口

陆城
2023-03-14

我正在运行基于这里所示示例的代码,在OS X上使用Eclipse,我正在使用JFreeChart和JCommon库。

正如我在标题中所说,程序正在运行,但没有显示任何内容。作为检查,我尝试使用printData()方法打印数据,它工作得非常好。它正确地从yahoo csv文件中获取数据。

我甚至尝试过使用一小部分数据(20行),但它一直不显示。

问题可能只是在显示JFrame窗口时。

我插入的试图修复它的代码位于//BEGIN和//END注释之间。

等待回复,

非常感谢。

半解决:代码很好,问题与JFreeChart库有关。

我试图“建立路径”

当我插入JFreeChart库时,它会禁止窗口显示。即使我不进口任何东西;只需将库添加到建筑路径即可。

作为默认系统库,我使用“JRE系统库[JavaSE-1.7]”。

代码:

package marketAnalyzer;
import org.jfree.chart.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.MovingAverage;
import org.jfree.data.xy.*;

import javax.swing.*;

import java.awt.*;
import java.io.*;
import java.net.URL;
import java.text.*;
import java.util.*;
import java.util.List;



public class CandlestickDemo extends JFrame {


    public CandlestickDemo(String stockSymbol) {
        super("CandlestickDemo");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        DateAxis    domainAxis       = new DateAxis("Date");
        NumberAxis  rangeAxis        = new NumberAxis("Price");
        CandlestickRenderer renderer = new CandlestickRenderer();
        XYDataset   dataset          = getDataSet(stockSymbol);

        XYPlot mainPlot = new XYPlot(dataset, domainAxis, rangeAxis, renderer);

        final long ONE_DAY = 24 * 60 * 60 * 1000;
        XYLineAndShapeRenderer maRenderer = new XYLineAndShapeRenderer(true, false);
        XYDataset              maSataset  = MovingAverage.createMovingAverage(dataset, "MA", 30 * ONE_DAY, 0);
        mainPlot.setRenderer(1, maRenderer);
        mainPlot.setDataset (1, maSataset);

        //Do some setting up, see the API Doc
        renderer.setSeriesPaint(0, Color.BLACK);
        renderer.setDrawVolume(false);
        rangeAxis.setAutoRangeIncludesZero(false);
        domainAxis.setTimeline( SegmentedTimeline.newMondayThroughFridayTimeline() );

        //Now create the chart and chart panel
        JFreeChart chart = new JFreeChart(stockSymbol, null, mainPlot, false);
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(600, 300));

        this.add(chartPanel);
        this.pack();

        //BEGIN

        //TRYING TO DISPLAY THE WINDOW

        chartPanel.setLayout(new java.awt.BorderLayout());
        chartPanel.validate();
        this.setLayout(new java.awt.BorderLayout());
        this.validate();
        chartPanel.repaint();
        this.repaint();


        //END
    }
    protected AbstractXYDataset getDataSet(String stockSymbol) {
        //This is the dataset we are going to create
        DefaultOHLCDataset result = null;
        //This is the data needed for the dataset
        OHLCDataItem[] data;

        //This is where we go get the data, replace with your own data source
        data = getData(stockSymbol);

        //Create a dataset, an Open, High, Low, Close dataset
        result = new DefaultOHLCDataset(stockSymbol, data);

        return result;
    }
    //This method uses yahoo finance to get the OHLC data
    protected OHLCDataItem[] getData(String stockSymbol) {
        List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>();
        try {
            //INTERNET DATA
            //              String strUrl= "http://ichart.finance.yahoo.com/table.csv?s="+stockSymbol+"&a=0&b=1&c=2008&d=3&e=30&f=2008&ignore=.csv";
            //              URL url = new URL(strUrl);
            //              BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            //              DateFormat df = new SimpleDateFormat("y-M-d");


            //BEGIN
            FileReader r;
            BufferedReader in;

            r = new FileReader("nasdaqSmall.csv");

            in = new BufferedReader(r);
            DateFormat df = new SimpleDateFormat("y-M-d");

            //END


            String inputLine;
            in.readLine();
            while ((inputLine = in.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(inputLine, ",");

                Date date       = df.parse( st.nextToken() );
                double open     = Double.parseDouble( st.nextToken() );
                double high     = Double.parseDouble( st.nextToken() );
                double low      = Double.parseDouble( st.nextToken() );
                double close    = Double.parseDouble( st.nextToken() );
                double volume   = Double.parseDouble( st.nextToken() );
                double adjClose = Double.parseDouble( st.nextToken() );

                OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume);
                dataItems.add(item);
            }
            in.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        //Data from Yahoo is from newest to oldest. Reverse so it is oldest to newest
        Collections.reverse(dataItems);

        //Convert the list into an array
        OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]);



        //BEGIN
        //DEBUG
        printData(data);
        //END

        return data;
    }

    public static void main(String[] args) {
        new CandlestickDemo("MSFT").setVisible(true);

    }

    //PRINT DATA
    public static void printData(OHLCDataItem[] data){
        for(OHLCDataItem el: data){
            System.out.println(""+el.getDate()+" "+el.getOpen()+" "+el.getHigh()+" "+el.getLow()+" "+el.getClose()+
                    " "+el.getVolume());

        }
    }


}

共有3个答案

朱昊乾
2023-03-14

试试这个:

您的类应该导入组织扩展应用程序框架。jfree。用户界面 包。现在不再使用frame。getContentPane()使用setContentPane(myChartPanel)

然后,您的代码应该如下所示:

final JFreeChart myChart = createChart(dataset);
    final ChartPanel myChartPanel = new ChartPanel(myChart);
    myChartPanel.setPreferredSize(new java.awt.Dimension(500, 500));
    setContentPane(myChartPanel);

温成济
2023-03-14

我看不出所有的验证/重新绘制有什么帮助。一般来说,如果要更改容器的布局管理器,请先更改,然后向其中添加组件。

JFrame包含一个JRootPane,它有一个contentPane。从技术上讲,您也需要在这个contentPane中添加组件。您可以使用框架getContentPane()方法实现这一点。但这确实变得很麻烦,所以JFrame变得更易于使用。从文档中:

为了方便添加及其变体,删除和setLayout已被重写,以便在必要时转发到内容窗格。这意味着你可以写:

   frame.add(child);   

子项将被添加到contentPane。

但是我不记得什么时候添加了这种便利——可能是Java6,所以确保你至少使用了jdk1.6。

另一件需要注意的事情是内容窗格的默认布局:

默认内容窗格将设置一个BorderLayout管理器。

所以也不需要设置框架来使用边框布局。使用BorderLayout时,您应该在添加组件时提供位置,例如BorderLayout。CENTER.碰巧的是,我不认为这是你的错误的原因,因为我认为默认情况下,它假设CENTER。但这仍然是很好的练习。

我必须承认,我总是使用更详细的版本,通过JFrames上的add()setLayout()直接与getContentPane()进行交互,而不是主要出于习惯而使用的方便方法,但它确实清楚地表明了我实际上在做什么。我建议你现在也这样做。

我创建了一个更小、更简单的应用程序版本,显示一个图表供您使用。

import javax.swing.*;
import java.awt.*;
import org.jfree.chart.*;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

class Test {

    private JFrame frame;

    public Test() {

        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel aPanel = new JPanel();
        aPanel.setPreferredSize(new Dimension(600, 300));


        ChartPanel chartPanel = new ChartPanel(createChart());
        chartPanel.setPreferredSize(new Dimension(600, 300));

        frame.getContentPane().add(chartPanel);

        frame.pack();
        frame.setVisible(true);
    }

    private JFreeChart createChart() {

        TimeSeries series = new TimeSeries("time series", Day.class);
        series.add(new Day(1,1,2014), 100 );  
        series.add(new Day(1,2,2014), 150);  
        series.add(new Day(1,3,2014), 70 );  
        series.add(new Day(1,4,2014), 210 );  
        series.add(new Day(1,5,2014), 310);
        series.add(new Day(1,6,2014), 260 );  
        TimeSeriesCollection dataset = new TimeSeriesCollection();  
        dataset.addSeries(series);  
        JFreeChart timechart = ChartFactory.createTimeSeriesChart(  
                "Vistors Count Chart", // Title  
                "Date",         // X-axis Label 
                "Visitors",       // Y-axis Label  
                dataset,        // Dataset  
                true,          // Show legend  
                true,          // Use tooltips  
                false          // Generate URLs  
        );

        return timechart;

    }

    public static void main(String[] args) {
        new Test();
    }

}

这个工作原理使用java/javac 1.7; jconus-1.0.23; jfreechart-1.0.19。

亢琦
2023-03-14

我也有这个问题。它来自于将JFreeChart库中的所有罐添加到构建路径。通过删除不必要的,并只添加jfreechart-1.0.19和jconom-1.0.23罐,我的应用程序开始运行的窗口和图表显示。

 类似资料:
  • 我有一个程序,在你点击一个动作按钮后,它会运行一个很长的过程。当进程正在运行时,根窗口会说它没有响应,即使我知道程序正在后台运行。这个程序将发布给我的几个同事,我想确保他们看到这个时不会惊慌失措并关闭窗口。我的解决办法是坐在树根上。正在运行的进程的循环中进行更新,但我不确定这是否是最佳修复方法。 使用Python3.3 这是一个代码的示例,所以你可以了解我在做什么,这是从主循环中调用的:

  • 我正在将vscode与eslint一起使用。eslint控制台显示以下内容: 因此eslint似乎正在加载和运行。但是,我的项目根目录中有一个文件,其中包含规则,并且vscode没有显示任何lting错误。 我如何调试这个?

  • 问题内容: 我已经开发了一个小应用程序来跟踪我的日常工作活动,该工具包含两个类: 执行者 UIProgress 我的目标是创建一个ProgressBar来更新执行状态,使用的逻辑如下所示, 根据Executor类中定义的executeTask(),我创建了UIProgress对象。 UIProgress类扩展了JFrame。创建一个面板,其中包含带有一个图像的标签和进度条。我已经在此类中定义了一个

  • 我开发了一个小应用程序来跟踪我的日常工作活动,该工具包含两个类: 遗嘱执行人 我的目标是创建一个更新执行状态的ProgressBar,下面给出了使用的逻辑, 从Exector类中定义的执行任务()中,我创建了UIProgress对象。 UIProgress类扩展了JFrame。创建一个包含带有一个图像和进度条的标签的面板。我在这个类中定义了一个方法updateProgress,它设置了进度条的值。

  • 我试图从扩展服务的类中打开一个活动。当应用程序不在前台/未被使用时,我正在执行此任务。我可以在日志中看到,我的服务类故意触发了启动活动。标志\活动\新任务标志。但活动并未开始。但是,当应用程序处于前台/正在使用时,服务触发相同的活动时,活动就会打开。 经过几次搜索,我发现我需要在应用程序设置的“其他权限”部分中手动授予“在后台运行android时显示弹出窗口”的权限。 “在其他应用程序上显示”权限