/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package hr.fer.zemris.vhdllab.applets.editor.newtb.view; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JComponent; /** * @author Ivan Brkic * @version 1.02 * @since 15. July 2008. */ public class ImpulsImageComponent extends JComponent { private static final long serialVersionUID = 4329423254661434581L; // private String scale; private int clockTimeHigh; private int clockTimeLow; private int inputSetupTime; // public void setScale(String scale){ // this.scale = scale; // } public void setClockTimeHigh(int clockTimeHigh) { this.clockTimeHigh = clockTimeHigh; } public void setClockTimeLow(int clockTimeLow) { this.clockTimeLow = clockTimeLow; } public void setInputSetupTime(int inputSetupTime) { this.inputSetupTime = inputSetupTime; } private boolean risingEdge = true; public void setRisingEdge(){ this.risingEdge = true; } public void setFallingEdge(){ this.risingEdge = false; } public void setRisingEdge(boolean b){ this.risingEdge = b; } private boolean combinatorial = true; public void setCombinatorial(){ this.combinatorial = true; } public void setSingleClock(){ this.combinatorial = false; } public void setCombinatorial(boolean b){ this.combinatorial = b; } private int checkedOutputs; public void setCheckedOutputs(int checkedOutputs){ this.checkedOutputs = checkedOutputs; } private int assignInputs; public void setAssignInputs(int assignInputs){ this.assignInputs = assignInputs; } private int width = 665; private int height = 200; /** default constuctor */ public ImpulsImageComponent() { this.setPreferredSize(new Dimension(width, height)); setVisible(true); } /** constructor which sets default values to current dialog's values */ public ImpulsImageComponent(InitTimingDialog dialog) { this.setPreferredSize(new Dimension(width, height)); this.clockTimeHigh = dialog.getClockTimeHigh(); this.clockTimeLow = dialog.getClockTimeLow(); this.inputSetupTime = dialog.getInputSetupTime(); this.checkedOutputs = dialog.getCheckOutputs(); this.assignInputs = dialog.getAssignInputs(); setVisible(true); } /** a value of height indents and voids*/ private int indentH = 10; /** a value of width indents and voids*/ private int indentW = 150; /** height of the impuls image */ private int impulsImageHeight = 140; /** width of the impuls image */ private int impulsImageWidth = width - 2*indentW; /** used for creating arrow */ private int triangleHeight = 10; /** used for combinatorial */ private int imageIndentW; /** string height */ private int stringHeight; @Override public void paintComponent(Graphics g) { super.paintComponents(g); imageIndentW = g.getFontMetrics().stringWidth("Outputs")/2; stringHeight = g.getFontMetrics().getHeight(); // g.setColor(Color.white); // g.fillRect(0, 0, width, height); if (this.combinatorial){ g.setColor(Color.BLACK); int sum = checkedOutputs + assignInputs; int a = Math.round(checkedOutputs * (impulsImageWidth- 2*imageIndentW) / sum); int b = Math.round(assignInputs * (impulsImageWidth- 2*imageIndentW) / sum); int impulsEndH = height - indentH; int impulsStartH = impulsEndH - impulsImageHeight; int impulsEndW = width - indentW; g.drawLine(indentW, impulsEndH, impulsEndW, impulsEndH); Color green = Color.GREEN.darker().darker(); writeStringOnTopArrow(g, "Assign", "Inputs", green, indentW+imageIndentW); writeStringOnTopArrow(g, "Assign", "Inputs", green, width-indentW-imageIndentW); writeStringOnTopArrow(g, "Check", "Outputs", Color.BLUE, indentW+imageIndentW+a); drawColorArrow(g, (impulsStartH+impulsEndH)/2, indentW+imageIndentW, a, "Wait To Check", Color.BLUE); drawColorArrow(g, (impulsStartH+impulsEndH)/2, indentW+imageIndentW+a, b, "Wait To Assign", green); }else{ // Single Clock ************************* g.setColor(Color.BLACK); int sum = clockTimeHigh + clockTimeLow; int impulsEndH = impulsImageHeight + indentH; int impulsEndW = width - indentW; int a; int c = Math.round(inputSetupTime * impulsImageWidth / sum); int bottomFieldHeight = height - impulsImageHeight - 3*indentH; int bottomColorArrowHeight = height-bottomFieldHeight/2-indentH; if (risingEdge){ // RISING EDGE *********************** drawTriangle(g, indentW, indentH, indentW-5, indentH+triangleHeight, indentW+5, indentH+triangleHeight); drawTriangle(g, width-indentW, indentH, impulsEndW-5, indentH+triangleHeight, impulsEndW+5, indentH+triangleHeight); g.drawLine(indentW, indentH+triangleHeight, indentW, impulsEndH); g.drawLine(impulsEndW, indentH+triangleHeight, impulsEndW, impulsEndH); a = Math.round(clockTimeHigh * impulsImageWidth / sum); int b = Math.round(clockTimeLow * impulsImageWidth / sum); g.drawLine(indentW, indentH, indentW+a, indentH); g.drawLine(indentW+a, indentH, indentW+a, impulsEndH); g.drawLine(indentW+a, impulsEndH, impulsEndW, impulsEndH); drawColorArrow(g, bottomColorArrowHeight, indentW, a, "Clock Time High", Color.MAGENTA); drawColorArrow(g, bottomColorArrowHeight, indentW+a, b, "Clock Time Low", Color.BLUE); }else{ // FALLING EDGE ******************************** drawTriangle(g, indentW, impulsEndH, indentW-5, impulsEndH-triangleHeight, indentW+5, impulsEndH-triangleHeight); drawTriangle(g, width-indentW, impulsEndH, impulsEndW-5, impulsEndH-triangleHeight, impulsEndW+5, impulsEndH-triangleHeight); g.drawLine(indentW, indentH, indentW, impulsEndH-triangleHeight); g.drawLine(width-indentW, indentH, impulsEndW, impulsEndH-triangleHeight); a = Math.round(clockTimeLow * impulsImageWidth / sum); int b = Math.round(clockTimeHigh * impulsImageWidth / sum); g.drawLine(indentW, impulsEndH, indentW+a, impulsEndH); g.drawLine(indentW+a, impulsEndH, indentW+a, indentH); g.drawLine(indentW+a, indentH, impulsEndW, indentH); drawColorArrow(g, bottomColorArrowHeight, indentW, a, "Clock Time Low", Color.MAGENTA); drawColorArrow(g, bottomColorArrowHeight, indentW+a, b, "Clock Time High", Color.BLUE); } drawColorArrow(g, impulsEndH/2, impulsEndW-c, c, "Input Setup Time", Color.GRAY); g.setColor(Color.GRAY); g.drawLine(indentW, impulsEndH+indentH, indentW, height-indentH); g.drawLine(indentW+a, impulsEndH+indentH, indentW+a, height-indentH); g.drawLine(impulsEndW, impulsEndH+indentH, impulsEndW, height-indentH); g.drawLine(impulsEndW-c, 2*indentH, impulsEndW-c, impulsEndH-indentH); } } /** draws triangle*/ private void drawTriangle(Graphics g, int x1, int y1, int x2, int y2, int x3, int y3){ g.drawLine(x1, y1, x2, y2); g.drawLine(x1, y1, x3, y3); g.drawLine(x3, y3, x2, y2); } private int triangleBase = 10; private void drawColorArrow(Graphics g, int y, int x, int width, String text, Color c){ g.setColor(c); int stringWidth = g.getFontMetrics().stringWidth(text); if (stringWidth + 10 + 2*triangleHeight + 10 < width){ g.drawString(text, x+(width-stringWidth)/2, y+stringHeight/4); fillTriangle(g, x, y, 1); fillTriangle(g, x + width, y, 2); int tempWidth = (width-stringWidth)/2 - 10 -triangleHeight; int tempHeight = triangleBase*2/3; int tempY = y-triangleBase/3; g.fillRect(x+5+triangleHeight, tempY, tempWidth, tempHeight); g.fillRect(x+width-5-triangleHeight-tempWidth, tempY, tempWidth, tempHeight); }else if(width > 10 + 2*triangleHeight){ fillTriangle(g, x, y, 1); fillTriangle(g, x + width, y, 2); int tempWidth = width - 10 -2*triangleHeight; int tempHeight = triangleBase*2/3; int tempY = y-triangleBase/3; g.fillRect(x+5+triangleHeight, tempY, tempWidth, tempHeight); } } /** * * @param type * 1 - left * 2 - right * 3 - bottom (given the lowest end) */ private void fillTriangle(Graphics g, int x, int y, int type){ int[] xField = new int [3]; int[] yField = new int [3]; yField[0] = y; if (type==1){ xField[0] = x+5; xField[1] = xField[2] = xField[0] + triangleHeight; yField[1] = y - triangleBase/2; yField[2] = y + triangleBase/2; }else if(type==2){ xField[0] = x - 5; xField[1] = xField[2] = xField[0] - triangleHeight; yField[1] = y - triangleBase/2; yField[2] = y + triangleBase/2; }else if(type==3){ xField[0] = x; xField[1] = x - triangleBase/2; xField[2] = x + triangleBase/2; yField[1] = yField[2] = y - triangleHeight; } g.fillPolygon(xField, yField, 3); } private void writeStringOnTopArrow(Graphics g, String top, String bottom, Color c, int x){ g.setColor(c); int stringWidth = g.getFontMetrics().stringWidth(top)/2; g.drawString(top, x-stringWidth, indentH+stringHeight/2); stringWidth = g.getFontMetrics().stringWidth(bottom)/2; g.drawString(bottom, x-stringWidth, indentH+3*stringHeight/2); g.drawLine(x, indentH+2*stringHeight, x, height-indentH-triangleHeight); fillTriangle(g, x, height-indentH, 3); } }