自定义图形 – Java Swing

我正在尝试用Java创建自定义动态直方图类型条形图。 我搜索了很多但是找不到实现这个目标的方法。

我知道JFreeChart库,但它不符合我的需求。 这就是JFreeChart直方图的样子:

在此处输入图像描述

但我想要的是一个只有X轴的动态直方图。
这个photoshopped图像将使它更容易理解。 在此处输入图像描述

JFrame将具有固定的边界。 如您所见,应该没有Y轴。 条形图的高度应根据值自动调​​整。

请帮我建立这个! 提前致谢。

一个穷人的直方图:

在此处输入图像描述

import java.awt.*; import java.util.List; import java.util.ArrayList; import javax.swing.*; import javax.swing.border.*; public class HistogramPanel extends JPanel { private int histogramHeight = 200; private int barWidth = 50; private int barGap = 10; private JPanel barPanel; private JPanel labelPanel; private List bars = new ArrayList(); public HistogramPanel() { setBorder( new EmptyBorder(10, 10, 10, 10) ); setLayout( new BorderLayout() ); barPanel = new JPanel( new GridLayout(1, 0, barGap, 0) ); Border outer = new MatteBorder(1, 1, 1, 1, Color.BLACK); Border inner = new EmptyBorder(10, 10, 0, 10); Border compound = new CompoundBorder(outer, inner); barPanel.setBorder( compound ); labelPanel = new JPanel( new GridLayout(1, 0, barGap, 0) ); labelPanel.setBorder( new EmptyBorder(5, 10, 0, 10) ); add(barPanel, BorderLayout.CENTER); add(labelPanel, BorderLayout.PAGE_END); } public void addHistogramColumn(String label, int value, Color color) { Bar bar = new Bar(label, value, color); bars.add( bar ); } public void layoutHistogram() { barPanel.removeAll(); labelPanel.removeAll(); int maxValue = 0; for (Bar bar: bars) maxValue = Math.max(maxValue, bar.getValue()); for (Bar bar: bars) { JLabel label = new JLabel(bar.getValue() + ""); label.setHorizontalTextPosition(JLabel.CENTER); label.setHorizontalAlignment(JLabel.CENTER); label.setVerticalTextPosition(JLabel.TOP); label.setVerticalAlignment(JLabel.BOTTOM); int barHeight = (bar.getValue() * histogramHeight) / maxValue; Icon icon = new ColorIcon(bar.getColor(), barWidth, barHeight); label.setIcon( icon ); barPanel.add( label ); JLabel barLabel = new JLabel( bar.getLabel() ); barLabel.setHorizontalAlignment(JLabel.CENTER); labelPanel.add( barLabel ); } } private class Bar { private String label; private int value; private Color color; public Bar(String label, int value, Color color) { this.label = label; this.value = value; this.color = color; } public String getLabel() { return label; } public int getValue() { return value; } public Color getColor() { return color; } } private class ColorIcon implements Icon { private int shadow = 3; private Color color; private int width; private int height; public ColorIcon(Color color, int width, int height) { this.color = color; this.width = width; this.height = height; } public int getIconWidth() { return width; } public int getIconHeight() { return height; } public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(color); g.fillRect(x, y, width - shadow, height); g.setColor(Color.GRAY); g.fillRect(x + width - shadow, y + shadow, shadow, height - shadow); } } private static void createAndShowGUI() { HistogramPanel panel = new HistogramPanel(); panel.addHistogramColumn("A", 350, Color.RED); panel.addHistogramColumn("B", 690, Color.YELLOW); panel.addHistogramColumn("C", 510, Color.BLUE); panel.addHistogramColumn("D", 570, Color.ORANGE); panel.addHistogramColumn("E", 180, Color.MAGENTA); panel.addHistogramColumn("F", 504, Color.CYAN); panel.layoutHistogram(); JFrame frame = new JFrame("Histogram Panel"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add( panel ); frame.setLocationByPlatform( true ); frame.pack(); frame.setVisible( true ); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } } 

我再给JFreeChart看一看。 您可以使范围轴不可见,而是使用项目标签。 没有图例,覆盖getItemPaint()可以提供任意颜色。 这里显示了另一种方法。

图片

 import java.awt.Color; import java.awt.EventQueue; import java.awt.Paint; import javax.swing.JFrame; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.renderer.category.BarRenderer; import org.jfree.chart.renderer.category.StandardBarPainter; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.ui.TextAnchor; /** * @see https://stackoverflow.com/a/29709153/230513 */ public class BarChart { private CategoryDataset createDataset() { String row = "Row"; DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(350, row, "A"); dataset.addValue(690, row, "B"); dataset.addValue(510, row, "C"); dataset.addValue(570, row, "D"); dataset.addValue(180, row, "E"); dataset.addValue(504, row, "F"); return dataset; } private JFreeChart createChart(CategoryDataset dataset) { CategoryAxis categoryAxis = new CategoryAxis(""); ValueAxis valueAxis = new NumberAxis(""); valueAxis.setVisible(false); BarRenderer renderer = new BarRenderer() { @Override public Paint getItemPaint(int row, int column) { switch (column) { case 0: return Color.red; case 1: return Color.yellow; case 2: return Color.blue; case 3: return Color.orange; case 4: return Color.gray; case 5: return Color.green.darker(); default: return Color.red; } } }; renderer.setDrawBarOutline(false); renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition( ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER)); renderer.setBaseItemLabelsVisible(Boolean.TRUE); renderer.setBarPainter(new StandardBarPainter()); CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer); JFreeChart chart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, plot, false); chart.setBackgroundPaint(Color.white); return chart; } private void display() { JFrame f = new JFrame("BarChart"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new ChartPanel(createChart(createDataset()))); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(() -> { new BarChart().display(); }); } }