私はプログラミング初心者なので、これが明らかな質問である場合はご容赦ください。ただし、ガント チャートを作成するアプリケーションに取り組んでいます。
私が抱えている問題は、パネルの 1 つ (namesPanel) に関連する画像が表示されますが、上部から約 10 ピクセルが欠落していることです。描画中に y 変数の開始点に 10 ピクセルを追加することで、画像が正しく見えるようにすることができますが、これは正しくないと感じます。バグがある場合は、今すぐつぶしたいと思います。
チャートは実際には、JPanel にネストされた 3 つの異なる JScrollPanes で構成され、GridBagLayout で配置されます。
datesPanel = new JScrollPane();
datesPane = new GanttPanel();
panelList.put(datesPanel, datesPane);
c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 1;
c.gridy = 0;
c.weightx = 0.1;
c.weighty = 0.1;
add(datesPanel, c);
namesPanel = new JScrollPane();
namesPane = new GanttPanel();
panelList.put(namesPanel, namesPane);
c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 1;
c.weightx = 0.18;
c.weighty = 1;
add(namesPanel, c);
ganttPanel = new JScrollPane();
ganttPane = new GanttPanel();
panelList.put(ganttPanel, ganttPane);
c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 1;
c.gridy = 1;
c.weightx = 1;
c.weighty = 1;
add(ganttPanel, c);
for (JScrollPane j : panelList.keySet()) {
GanttPanel g = panelList.get(j);
j.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
j.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
j.addMouseListener(listener);
LineBorder b = (LineBorder) BorderFactory.createLineBorder(DARK);
j.setBorder(b);
j.setViewportView(g);
}
namesImage = (BufferedImage) namesPane.createImage(canvasWidth, canvasDepth);
namesPane.setImage(namesImage);
namesGraphics = (Graphics2D) namesImage.getGraphics();
datesImage = (BufferedImage) datesPane.createImage(canvasWidth, canvasDepth);
datesPane.setImage(datesImage);
datesGraphics = (Graphics2D) datesImage.getGraphics();
ganttImage = (BufferedImage) ganttPane.createImage(canvasWidth, canvasDepth);
ganttPane.setImage(ganttImage);
graphics = (Graphics2D) ganttImage.getGraphics();
この理由は、ユーザーがマウスを使用して ganttChart をスクロールできるようにするためです。これにより、後で、namesPanel と datesPanel のスクロールバーが ganttChart と同じ JScrollBar のインスタンスに設定されます。
次に、プログラムはメモリを節約するためにすべての画像のサイズを変更します。最初にすべての画像が同じサイズに設定されているのは、最終的な画像の境界を設定するために特定のグラフィックス計算が必要なためです。グラフィックス オブジェクトを取得するイメージ。また、画像を大きくする方法がわかりません:
/**
* Sets the boundaries of all the panels and moves them into position
*/
private void setBounds()
{
int xStart = canvasWidth - xOffset;
int yStart = canvasDepth - yOffset;
Container dad = getParent();
Rectangle dadRect = dad.getBounds();
Dimension ganttSize = new Dimension(dadRect.width - xOffset, dadRect.height - yOffset);
ganttImage = ganttImage.getSubimage(0, 0, xStart, yStart);
ganttPane.setPreferredSize(new Dimension(xStart, yStart));
ganttPanel.setPreferredSize(ganttSize);
datesImage = datesImage.getSubimage(0, 0, xStart, (yOffset + yUnit));
datesPane.setPreferredSize(new Dimension(xStart, yOffset));
datesPanel.setPreferredSize(new Dimension(xStart, yOffset));
namesImage = namesImage.getSubimage(0, 0, xOffset, yOffset);
namesPane.setPreferredSize(new Dimension(xOffset, yStart));
namesPanel.setPreferredSize(new Dimension(xOffset, yStart));
namesPanel.setBackground(DARK);
}
最後に、プログラムは実際に画像を描画します。この領域にはサブメソッドへのリファクタリングが必要であることはわかっていますが、次のとおりです。
/**
* Draw the bars of the Gantt Chart
*/
private void drawBars()
{
Calendar from = model.getFrom();
int i = 0;
for (int y = 0; y < canvasDepth && i < elements.size(); y += yUnit) {
GanttElement ge = elements.get(i);
//TODO refactor this section into multiple methods
int startPoint = 0;
int endPoint = 0;
try {
startPoint = (model.calculateRange(from, ge.getFrom()) * xUnit);
if (startPoint % 10 != 0) {
startPoint -= startPoint % 10;
}
endPoint = (model.calculateRange(from, ge.getTo()) * xUnit);
}
catch (IllegalArgumentException | BadDateException e) {
/*TODO add a badDateResponse method to the GanttElement interface
*so that the program can handle a bad date request appropriately
*/
System.out.println(e + " " + ge.getName());
}
for (int x = 0; x <= endPoint; x += xUnit) {
if (x == 0) {
namesGraphics.setColor(Color.WHITE);
namesGraphics.drawString(ge.getName(), (2 * getSeparatorX()), y);
}
if (i % 2 == 0) {
graphics.setColor(lightBlock);
}
else {
graphics.setColor(darkBlock);
}
if (x >= startPoint) {
GanttBlock block = new GanttBlock(x + (separatorX / 2), y, blockWidth, rowHeight, i);
blocks.add(block);
graphics.fill(block);
}
}
i++;
}
}
私は困惑しています-問題の原因となっている行を見つけることができず、namesPanel の処理方法と他の処理方法との違いがわかりません。画像の配置と寸法に影響を与えるフィールドを変更しても役に立ちません。JViewport を操作することもできません。:-(
繰り返しになりますが、これが長すぎる場合は申し訳ありませんが、コードのどの領域に注目すればよいかわかりません。