由於本週六在學校項目上工作時,遇到了我遇到過的最煩人的bug。我似乎無法在萬維網上的任何地方找到解決方案。即使我的好朋友谷歌似乎讓我失望。所以,這裏的問題:轉換後的JTabbedPane轉換內容
我正在與JTabbedPane。在這個JTabbedPane中,我會展示不同的JPanes,每個都顯示他們的信息。在其中一個JPane中,我正在繪製一個條形圖。
分別測試條形圖時,它一切正常。當我在JTabbedPane的正確選項卡中加載我的信息時也會這樣。但是,只要切換回此選項卡,繪圖過程中的柱狀圖就會向上移動,並且看起來都是扭曲的東西(參見圖片)。
我知道一個事實,即我正在繪製正確的coördinates,所以它必須是我的JPanel取代JTabbedPane的選項卡。你們有什麼想法是什麼導致這種奇怪的行爲?
右:它應該如何。左:切換回此選項卡後的外觀。
我BarGraphPanel類是一個真正的混亂,這裏是代碼:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package gui;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.text.DecimalFormat;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* @author Scuba Kay
*/
public class BarGraphPanel extends JPanel implements ManagementPanel {
private ArrayList<String[]> info;
private String infoName;
private double maxValue;
private int size;
private int barWidth;
private double left;
private double right;
private double width;
private double height;
private double bottom;
private double top;
private int barSpacing;
private double barPart;
private double graphHeight;
private double graphWidth;
private int cap;
public BarGraphPanel(){
super();
width = 600;
height = 480;
setSize((int) width, (int) height);
// The maximum number of results to show
cap = 30;
this.infoName = "Management information";
this.add(new JLabel("This query is not suited for Bar Graph view: please select another one."));
}
/**
* Sets both x and y, min and max and the info list
* @author Kay van Bree
* @param info
*/
@Override
public void setManagementInfo(ArrayList<String[]> info) {
reset();
this.info = info;
// Set important values
this.maxValue = getMaxValue(info);
this.size = info.size();
setSizes();
repaint();
}
/**
* Resets the panel, taken from TablePanel
* @author Joepe Kemperman
*/
public void reset() {
removeAll();
invalidate();
validate();
}
/**
* Set the sizes needed for calculating bar heights etc.
* @author Kay van Bree
*/
protected void setSizes(){
left = (width/100) * 7;
right = width - left*3;
top = (height/100) * 7;
bottom = height - top*3;
// The dimensions of the graph
graphHeight = bottom - top;
graphWidth = right - left;
// barWidth is... Just guess what it is.
barWidth = (int) ((double) (graphWidth/size) * 0.95);
// barSpacing is the space between the bars
barSpacing = (int) (graphWidth - (barWidth*size))/size;
if(barSpacing == 0){
barSpacing++;
barWidth--;
}
// barPart is the height of a bar of value 1
barPart = graphHeight/maxValue;
}
/**
* Return the max value of the info arraylist
* @author Kay van Bree
* @param info
*/
private int getMaxValue(ArrayList<String[]> info){
int max = 0;
for(String[] row: info){
if(Integer.valueOf(row[1]) > max){
max = Integer.valueOf(row[1]);
}
}
return max;
}
/**
* Draw the damn thing!
* @author Kay van Bree
* @param g
*/
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(info != null){
g.setColor(Color.BLACK);
drawTitle(g);
drawBlocks(g);
if(size <= cap){
drawBars(g);
} else {
drawError(g);
}
drawAxes(g);
} else {
this.setInformationNotSuitable();
}
}
/**
* Set an error displaying to many results
* @author Kay van Bree
* @param g
*/
private void drawError(Graphics g){
g.setColor(Color.BLACK);
g.drawString("Too many results to show!", (int)(right-left*2)/2, (int)(bottom-top*2)/2);
}
/**
* Draw the names under the bars
* @author Kay van Bree
* @param g
*/
private void drawName(Graphics g, String name, int x){
Graphics2D g2d = (Graphics2D)g;
// clockwise 90 degrees
AffineTransform at = new AffineTransform();
// thanks to M.C. Henle for the bug fix!
at.setToRotation(Math.PI/2.0, x + (barWidth/4), bottom + 3);
g2d.setTransform(at);
g2d.setColor(Color.BLACK);
g2d.drawString(name, (int) (x + (barWidth/4)), (int) bottom + 3);
g2d.setTransform(new AffineTransform());
}
/**
* Draw the lines behind the bars
* @author Kay van Bree
* @param g
*/
private void drawBlocks(Graphics g){
g.setColor(Color.lightGray);
// Ten parts
double part = maxValue/10;
double total = maxValue;
// Draw the numbers
for(int i=0; i<10; i++){
double y = (((bottom-top)/10)*i)+top;
g.drawLine(((int) left)-5, (int) y, ((int) right), (int) y);
}
g.drawLine((int) right, (int) top, (int) right, (int) bottom);
}
/**
* Draw the title of the Graph
* @author Kay van Bree
* @param g
*/
private void drawTitle(Graphics g){
int tLeft = 100;
g.drawString(infoName, tLeft, (int) top/2);
}
/**
* Draw the axes of this Bar Graph
* @author Kay van Bree
* @param g
*/
private void drawAxes(Graphics g){
g.setColor(Color.BLACK);
// draw lines from (x, y) to (x, y)
g.drawLine((int) left, (int) top, (int) left, (int) bottom);
g.drawLine((int) left, (int) bottom, (int) right, (int) bottom);
// Ten parts
double part = maxValue/10;
double total = maxValue;
// Draw the numbers
for(int i=0; i<10; i++){
double y = (((bottom-top)/10)*i)+top;
String number = round(total);
FontMetrics fontMetrics = g.getFontMetrics();
g.drawString(number, (int) (left * 0.80) - fontMetrics.stringWidth(number), ((int) y)+5);
total = (total - part);
g.drawLine(((int) left)-5 , (int) y, ((int) left), (int) y);
}
}
/**
* Rounds the number to 1 decimal
* @author Kay van Bree
* @param number
* @return
*/
private String round(double number){
DecimalFormat df = new DecimalFormat("#.#");
Double dubbel = new Double(number);
return df.format(dubbel);
}
/**
* Round a number, make it int
* @author Kay van Bree
* @param number
* @return
*/
private int roundToInt(double number){
DecimalFormat df = new DecimalFormat("#");
Double dubbel = new Double(number);
return Integer.valueOf(df.format(dubbel));
}
/**
* We need info right?
* Then draw the damn bars already!
* @author Kay van Bree
* @param g
*/
private void drawBars(Graphics g){
double currentX = left + barSpacing + 1;
for(String[] row: info){
double value = Integer.valueOf(row[1]);
double barHeight = (value * barPart);
System.out.println("Value: " + value + " height: " + barHeight + " top: " + top);
double barStart = bottom - barHeight;
System.out.println("Barstart: " + barStart);
barHeight = ((int) bottom - (int) barStart);
g.setColor(Color.BLUE);
g.fillRect((int) currentX, (int) barStart, (int) barWidth, roundToInt(barHeight));
drawName(g, row[0], (int) currentX);
currentX = (currentX + barSpacing + barWidth);
}
}
public void setInformationNotSuitable() {
// JOptionPane.showMessageDialog(this, "This query is not suited for Bar Graph view. Please select another", "INSANE WARNING!", JOptionPane.WARNING_MESSAGE);
}
}
一些有益的信息:
setManagementInformation由JTabbedPane中調用一次。在這裏,它加載的所有內容(也其他標籤)
編輯 奧凱,所以至強的回答幾乎固定我的問題。我每次切換回該選項卡時,我的圖形條都會完美對齊。但是,切換回來時,欄下方的名稱仍然在移動。這裏是我更新的代碼:
/**
* Draw the names under the bars
* @author Kay van Bree
* @param g
*/
private void drawName(Graphics g, String name, int x){
Graphics2D g2d = (Graphics2D) g.create();
// Clockwise 90 degrees
AffineTransform at = new AffineTransform();
// Rotate the text
at.setToRotation(Math.PI/2.0, x + (barWidth/4), bottom + 3);
AffineTransform prev = g2d.getTransform();
g2d.setTransform(at);
g2d.setColor(Color.BLACK);
g2d.drawString(name, (int) (x + (barWidth/4)), (int) bottom + 3);
g2d.dispose();
}
那麼,這是否也有一些做的的AffineTransform,並沒有任何人有一個解決這個問題?
僅供參考,在將來,[功課]標籤添加到事情學校項目。 (這次我已經爲你添加了它。) –
我會懷疑在設置組件的大小和JTabbedPane的默認佈局管理器之間存在衝突。不是在構造函數中設置大小,而是設置首選大小並告訴我們它是如何發生的。 –
爲了儘快提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –