jFreeChart - rysowanie wykresu na części okna

0

Witam,

Mam pewien problem. Mianowicie chcę CZĘŚĆ okna przeznaczyć na narysowanie wykresu przy pomocy biblioteki jfreechart. O ile samo rysowanie wykresu i jego upiększanie nie jest już większym problemem to od wielu dni nie mogę przejść jednego tematu. Załóżmy, że zdefiniowałem okienko o wymiarach 1000x800 punktów. Jednak wykres chcę narysować na "dolnej" części okna powiedzmy o wymiarach 1000x700 czyli 100 górnych punktów pozostaje puste. I tu jest właśnie problem, za nic nie potrafię tego zrobić. Co bym nie kombinował to i tak wykres zawsze zajmuje pełne okno. Czy ktoś może podpowiedzieć "szablon" takiej klasy?

0

Można to zrobić np w ten sposób ale trzeba uwzględnić, że nie cały obszar ramki jest dostępny dla panelu (panel ma mniejsze wymiary niż ramka):

package pl.programmers.jfreechart;

import java.awt.*;

import static javax.swing.WindowConstants.*;

/**
 * Author: Daniel
 */
public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                ChartFrame chartFrame = new ChartFrame();
                chartFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                chartFrame.setVisible(true);
            }
        });
    }
}
package pl.programmers.jfreechart;

import javax.swing.*;
import java.awt.*;

/**
 * Author: Daniel
 */
public class ChartFrame extends JFrame {

    public ChartFrame() {
        prepareFrame();
        initializeComponents();
    }

    private void prepareFrame() {
        setSize(1000, 700);
        setLayout(null);
    }

    private void initializeComponents() {
        JPanel upPanel = new JPanel();
        upPanel.setBounds(0, 0, getWidth(), 100);
        upPanel.setBackground(Color.black);

        JPanel bottomPanel = new JPanel();
        bottomPanel.setBounds(0, 100, getWidth(), 600);
        bottomPanel.setBackground(Color.blue);

        add(upPanel);
        add(bottomPanel);
    }
}
0

Dzięki za szybką odpowiedź, zaraz posprawdzam choć wydaje mi się, że sprawdzałem takie konstrukcje. Dam odpowiedź co i jak.

0

Ja bym sugerował takie rozwiązanie:

public class ChartFrame extends JFrame {
 
    public ChartFrame() {
        initializeComponents();
    }
 
    private void initializeComponents() {
        JPanel upPanel = new UpperPanel(); 
        JPanel bottomPanel = new BottomPanel();
 
        add(upPanel,BorderLayout.NORTH);
        add(bottomPanel,BorderLayout.CENTER);
    }
    class UpperPanel extends JPanel
    {
         public UpperPanel
         {
              setPreferredSize(new Dimension(1000,100));
              setBackground(Color.BLACK);
         }
    }
    class BottomPanel extends JPanel
    {
         public BottomPanel
         {
              setPreferredSize(new Dimension(1000,700));
              setBackground(Color.WHITE);
         }
    }
}
0

Kurcze nie wiem .... dalej mi nic nie wychodzi. Czy możecie zerknąć w czym jest problem? Definicja paneli i okienek jest w liniach 39-58 reszta to upiększanie wykresu.

package org.jfree.chart.demo;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.text.NumberFormat;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.Align;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class BarChartDemo extends ApplicationFrame {

  	private static final long serialVersionUID = 1L;

	public BarChartDemo(final String title) {

        super(title);
        
        JFrame frame = new JFrame();
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
        setSize(800,500);
        setLayout(null);
        
        JPanel upPanel= new JPanel();
        upPanel.setBounds(0,0,800,100);
        upPanel.setBackground(Color.black);
        
        JPanel bottomPanel= new JPanel();
        bottomPanel.setBounds(0,100,800,500);
        bottomPanel.setBackground(Color.blue);
        
        frame.add(upPanel);
        frame.add(bottomPanel);
        
        final CategoryDataset dataset = createDataset();
        final JFreeChart chart = createChart(dataset);
        final ChartPanel chartPanel = new ChartPanel(chart);
        bottomPanel.add(chartPanel);
        
        ImageIcon icon = new ImageIcon("TloWykresu1.jpg"); 
        
        chart.setBackgroundImage(icon.getImage());
        chart.setBackgroundImageAlignment(Align.FIT);
        chart.setBackgroundImageAlpha(0.9f);
        //setContentPane(chartPanel);
        setContentPane(bottomPanel);
        
    }

   private CategoryDataset createDataset() {
        
        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(3.35, "", "1601-brzeski");
        dataset.addValue(15.07, "", "1602-głubczycki");
        dataset.addValue(5.90, "", "1603-kędzierzyńsko-kozielski");
        dataset.addValue(2.63, "", "1604-kluczborski");
        dataset.addValue(5.25, "", "1605-krapkowicki");
        dataset.addValue(8.32, "", "1606-namysłowski");
        dataset.addValue(11.15, "", "1607-nyski");
        dataset.addValue(3.39, "", "1608-oleski");
        dataset.addValue(3.97, "", "1609-opolski");
        dataset.addValue(3.20, "", "1610-prudnicki");
        dataset.addValue(2.80, "", "1611-strzelecki");
        dataset.addValue(16.45, "", "1661-Opole");

        return dataset;
        
    }
    
    @SuppressWarnings("deprecation")
	private JFreeChart createChart(final CategoryDataset dataset) {
        
        // create the chart...
        final JFreeChart chart = ChartFactory.createBarChart(
            "Liczba łóżek na 1000 mieszkańców",         // chart title
            "16 - województwo opolskie",               // domain axis label
            "Liczba łóżek",                  // range axis label
            dataset,                  // data
            PlotOrientation.VERTICAL, // orientation
            false,                     // include legend
            true,                     // tooltips?
            false                     // URLs?
        );
        
        final CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.darkGray);
        plot.setRangeGridlinePaint(Color.darkGray);
        
        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
       
        final BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(true);
              
        final GradientPaint gp0 = new GradientPaint(
            0.0f, 0.0f, Color.lightGray, 
            0.0f, 0.0f, Color.blue
        );
        final GradientPaint gp1 = new GradientPaint(
            0.0f, 0.0f, Color.green, 
            0.0f, 0.0f, Color.lightGray
        );
        final GradientPaint gp2 = new GradientPaint(
            0.0f, 0.0f, Color.red, 
            0.0f, 0.0f, Color.lightGray
        );
        renderer.setSeriesPaint(0, gp0);
        renderer.setSeriesPaint(1, gp1);
        renderer.setSeriesPaint(2, gp2);
        
        final CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(
            CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)
        );
        
        Font font = new Font("Dialog", Font.BOLD, 16);
        domainAxis.setTickLabelFont(font);
        
        Font font1 = new Font("Dialog", Font.BOLD, 24);
        domainAxis.setLabelFont(font1);

        CategoryItemRenderer itemRenderer = plot.getRenderer();
        CategoryItemLabelGenerator generator = new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getInstance());
        itemRenderer.setItemLabelGenerator(generator);
        itemRenderer.setItemLabelsVisible(true);
        Font font2 = new Font("Dialog", Font.BOLD, 12);
        itemRenderer.setBaseItemLabelFont(font2);
        
        plot.setBackgroundPaint(null);
                                     
        return chart;
        
    }
    
    public static void main(final String[] args) {

        final BarChartDemo demo = new BarChartDemo("XX");
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);

    }

}
0

Zrob to tak jak napisal bogdans albo ja kilka postow wczesniej. Niech glowna klasa BarChartDemo rozszerza JFrame i wewnatrz konstruktora ustaw dla niej layout na null. Wylacysz tym samym zarzadce ukladu dla ramki i sam bedziesz musial zdefiniowa gdzie i jakiej wielkosci komponenty bediesz na niej umieszczel. Bledy w Twoim kodzie sa takie ze rozszerzasz AplicationFrame zamiast JFrame i niepotrzebnie deklarujesz Jframe w konstruktorze skoro nic z nia nie robisz. Daj znac czy pomoglo.

0

OK dzięki za wskazówki. Zrobię jak radzisz ale odezwę się pewnie dopiero w poniedziałek.

BTW szukam kogoś do pomocy w projekcie, który na podstawie masy danych przedstawia na portalu www jeszcze większą masę wykresów i tabel przestawnych. Innym słowem serwlety tworzące dynamicznie wykresy na podstawie danych z SQL sparametryzowanych ze strony www. Nie ukrywam że Javy się uczę dopiero a wolałbym zająć się merytoryką a programowanie zostawić komuś kto się na tym zna.

0

Udało się! Dziękuję Panowie!

Załączam kod. Na pewno się komuś przyda, gdyż poustawianych jest sporo opcji wykresu.

Założenie jest takie:
Jest okienko podzielone na 3 części. Górna wąska na tytuły, dolna wąska na status i środkowa na wykres. Całe okno ma obrazek będący tłem dla wszystkich elementów, a wszystkie panele i wykres mają przeźroczyste tło, tak aby było widać właśnie ten rysunek.

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GradientPaint;
import java.text.NumberFormat;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.Align;


public class BarChartDemo extends JFrame{

	private static final long serialVersionUID = 1L;

	public BarChartDemo()
	{
		setSize(1360,922);	//ustawiamy wielkość okienka
		setLayout(null);	//wywalamy layout czyli wszystko ręcznie
				
		//definiujemy górny panel rozmiar, położenie i kolor wraz z kanałem Alpha
		JPanel upPanel = new JPanel();
		upPanel.setBounds(0, 0, 1342, 100);
		upPanel.setBackground(new Color(0.0f,0.0f,0.0f,0.0f));
		
		//definiujemy dolny panel rozmiar, położenie i kolor wraz z kanałem Alpha
		JPanel bottomPanel=new JPanel();
		bottomPanel.setBounds(0,822,1342,100);
		bottomPanel.setBackground(new Color(0.0f,0.0f,0.0f,0.0f));
			
		//wywołujemy metody tworzące wykres
		final CategoryDataset dataset = createDataset();
        final JFreeChart chart = createChart(dataset);
        final ChartPanel chartPanel = new ChartPanel(chart);
        
        //definiujemy rozmiar ramki panelu wykresu i kolor wraz z kanałem Alpha
        chartPanel.setBounds(0,100,1342,722);
        chartPanel.setBackground(new Color(0.0f,0.0f,0.0f,0.0f));
        
        //definiujemy rozmiar wykresu wewnątrz ramki wykresu i kolor wraz z kanałem Alpha
        chart.setBackgroundPaint(new Color(0.0f,0.0f,0.0f,0.0f));
        
        //dodajemy panele do ramki
        add(chartPanel);
        add(upPanel);
		add(bottomPanel);
		
		//dodajemy obrazek będący tłem całej ramki
		JLabel tlo=new JLabel(new ImageIcon("TloWykresu1.jpg"));
		tlo.setBounds(0, 0, 1342, 877);
		add(tlo);
	}
	
//ponniżej metoda tworząca dataset z danymi do wykresu	
private CategoryDataset createDataset() {
        
        // create the dataset...
        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        
        dataset.addValue(3.35, "", "1601-brzeski");
        dataset.addValue(15.07, "", "1602-głubczycki");
        dataset.addValue(5.90, "", "1603-kędzierzyńsko-kozielski");
        dataset.addValue(2.63, "", "1604-kluczborski");
        dataset.addValue(5.25, "", "1605-krapkowicki");
        dataset.addValue(8.32, "", "1606-namysłowski");
        dataset.addValue(11.15, "", "1607-nyski");
        dataset.addValue(3.39, "", "1608-oleski");
        dataset.addValue(3.97, "", "1609-opolski");
        dataset.addValue(3.20, "", "1610-prudnicki");
        dataset.addValue(2.80, "", "1611-strzelecki");
        dataset.addValue(16.45, "", "1661-Opole");
       
        return dataset;
        
    }
	
//poniżej metoda tworząca wykres	
private JFreeChart createChart(final CategoryDataset dataset) {
        
        // tworzymy wykres...
        final JFreeChart chart = ChartFactory.createBarChart(
            "",         // tytuł wykresu
            "",               // tytuł osi X
            "Liczba łóżek",                  // tytuł osi Y
            dataset,                  // dane wykresu
            PlotOrientation.VERTICAL, // orientacja wykresu
            false,                     // czy jest legenda
            true,                     // czy są tooltips?
            false                     // czy jest URLs?
        );
                 
        // teraz upiększamy wykres
        final CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.darkGray);
        plot.setRangeGridlinePaint(Color.darkGray);
        
        // ustawiamy wyświetlanie cyferek na osi X...
        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        //rangeAxis.setUpperMargin(0.05);

        // ramka punktów danych
        final BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(true);
              
        // ustawiamy gradientowe wypełnienie słupków danych
        final GradientPaint gp0 = new GradientPaint(
            0.0f, 0.0f, Color.lightGray, 
            0.0f, 0.0f, Color.blue
        );
        
        renderer.setSeriesPaint(0, gp0);
              
        final CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(
            CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)
        );
        
        //ustawiamy font dla etykiet na osi X
        Font font = new Font("Dialog", Font.BOLD, 16);
        domainAxis.setTickLabelFont(font);
        
        //ustawiamy font dla tytułu osi X
        Font font1 = new Font("Dialog", Font.BOLD, 24);
        domainAxis.setLabelFont(font1);

        //włączamy etykiety z danymi dla słupków
        CategoryItemRenderer itemRenderer = plot.getRenderer();
        CategoryItemLabelGenerator generator = new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getInstance());
        itemRenderer.setItemLabelGenerator(generator);
        itemRenderer.setItemLabelsVisible(true);
        Font font2 = new Font("Dialog", Font.BOLD, 12);
        itemRenderer.setBaseItemLabelFont(font2);
        
        plot.setBackgroundPaint(null);
                                     
        return chart;
        
    }
	
	public static void main(String[] args) {
		
		EventQueue.invokeLater(new Runnable()
		{
			@Override
			public void run() {
				
				BarChartDemo chartFrame = new BarChartDemo();
				
				ImageIcon icon = new ImageIcon("logov1.png");
				chartFrame.setIconImage(icon.getImage()); //tu ustawiamy mini ikonkę okna 
				
				chartFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
				
				chartFrame.setVisible(true);
			}
			
		});
	}

}
```java

0

Na przyszłość postaraj się nie tworzyć metod po 50 linijek albo więcej i przenosić kod do poszczególnych klas za to odpowiedzialnych.
Obecnie masz model, widok i kontroler w jednej klasie.

Poczytaj trochę:
http://pl.wikipedia.org/wiki/Model-View-Controller

0

Poza tym po kliknięciu na wykresie dzieją sie dziwne rzeczy.

0

Fakt powiela wykres w pomniejszonej wersji .... jeszcze nie wiem dlaczego.

0

bakeraw2 .... może masz jakąś podpowiedź w związku z tymi zachowaniami po kliknięciu?

0

Tworzyłem obsługę zdarzenia przy klikaniu, obsługa działa OK ale to nadpisywanie wykresu pozostało tak jak było.

1 użytkowników online, w tym zalogowanych: 0, gości: 1