| 1 3 5 22 23 package edu.neu.ccs.jmk.awt; 24 25 import java.io.*; 26 import java.awt.*; 27 import java.awt.datatransfer.*; 28 import java.awt.event.*; 29 import java.text.DateFormat ; 30 import java.util.*; 31 import edu.neu.ccs.jmk.*; 32 33 38 public class MakeWindow 39 extends TextArea 40 implements ActionListener, ClipboardOwner 41 { 42 private final static String JMK_PROPERTIES = "jmk"; 43 private final static String DEFAULT_FONT = "monoSpaced"; 44 private final static int DEFAULT_COLUMNS = 72; 45 private final static int DEFAULT_ROWS = 22; 46 47 private final static int MAX_TEXT_AREA = 16384; 48 private final static int TRUNCATED_TEXT_AREA = MAX_TEXT_AREA / 2; 49 private final String nl = System.getProperty("line.separator"); 50 52 private Make make; 53 private String [] targets; 54 private final RunQueue tasks = new RunQueue(); 55 56 63 MakeWindow(Make make, String [] targets, 64 int rows, int columns) { 65 this.make = make; 66 this.targets = targets; 67 setRows(rows); 68 setColumns(columns); 69 make.setOut(new PrintWriter(new MakeWriter(), true)); 71 new Thread (tasks).start(); 72 } 73 74 79 void appendLine(String s) { 80 append(s + nl); 81 setCaretPosition(Integer.MAX_VALUE); 82 String area = getText(); 83 int n = area.length(); if (n > MAX_TEXT_AREA) { 85 int truncSize = area.indexOf('\n', n - TRUNCATED_TEXT_AREA); 86 area = area.substring(truncSize); 87 setText(area); 88 } 89 } 90 91 96 void appendLongLine(String line) { 97 int columns = getColumns() - 5; 98 String prefix = ""; int cc = 0; int ls = 0; int s = 0; int n = line.length(); for (int i = 0; i < n; i++) { 104 if (line.charAt(i) == '\n') { 105 cc = 0; 106 ls = i + 1; } 108 else if (Character.isSpaceChar(line.charAt(i))) { 109 ls = i; 110 cc++; 111 } 112 else if (cc >= columns && Character.isSpaceChar(line.charAt(ls))) { 113 appendLine(prefix + line.substring(s, ls) + " \\"); 114 cc = 0; i = ls; ls = i + 1; s = ls; prefix = " "; } 120 else 121 cc++; 122 } 123 if (s < n) { appendLine(prefix + line.substring(s, n)); 125 } 126 } 127 128 class MakeWriter 129 extends Writer 130 { 131 StringBuffer buffer = new StringBuffer (DEFAULT_COLUMNS); 132 boolean eol = false; 133 boolean closed = false; 134 135 public void write (char cbuf[], int off, int len) 136 throws IOException 137 { 138 if (closed) 139 throw new IOException("Write of a closed writer"); 140 for (int i = off; i < len; i++) { 141 char ch = cbuf[i]; 142 if (eol) { 143 eol = false; 144 if (ch == '\n') 145 continue; 146 } 147 if (ch == '\n' || ch == '\r') { 148 if (ch == '\r') 149 eol = true; 150 appendLongLine(buffer.toString()); 151 buffer.setLength(0); 152 } 153 else { 154 buffer.append(ch); 155 } 156 } 157 } 158 159 public void flush() 160 throws IOException 161 { 162 if (closed) 163 throw new IOException("Flush of a closed writer"); 164 } 165 166 public void close() 167 throws IOException 168 { 169 if (!closed) { 170 flush(); 171 closed = true; 172 } 173 } 174 } 175 176 private String cachedTargetString; 177 178 183 public void actionPerformed(ActionEvent e) { 184 String targetString = e.getActionCommand().trim(); 185 if (!cachedTargetString.equals(targetString)) { 186 cachedTargetString = targetString; 187 targets = string2String_array(targetString); 188 } 189 make(); 190 } 191 192 196 private static String [] string2String_array(String str) { 197 Vector v = new Vector(); 198 int s = 0; 200 while (s < str.length()) { 201 if (str.charAt(s) == ' ') 202 s++; 203 else { 204 int e = str.indexOf(' ', s); if (e < 0) { 206 v.addElement(str.substring(s)); 207 break; 208 } 209 v.addElement(str.substring(s, e)); 210 s = e + 1; 211 } 212 } 213 214 String [] str_array = new String [v.size()]; 215 v.copyInto(str_array); 216 return str_array; 217 } 218 219 222 private String getTargetString() { 223 if (cachedTargetString == null) { 224 if (targets.length > 0) { 225 cachedTargetString = targets[0]; 226 for (int i = 1; i < targets.length; i++) 227 cachedTargetString += " " + targets[i]; 228 } 229 else 230 cachedTargetString = ""; 231 } 232 return cachedTargetString; 233 } 234 235 238 private void makeTask(String [] args, String targetString) { 239 try { 240 if (!make.make(args)) 241 make.getOut().println("Nothing to make"); 242 } 243 catch (CommandFailedException ex) { 244 make.getOut().println("Command failed: " + ex.getMessage()); 245 } 246 if (targetString.equals("")) 247 targetString = "Make"; 248 else 249 targetString = "Made " + targetString; 250 make.getOut().println(targetString + " at " + now()); 251 } 252 253 private DateFormat formatter; 254 255 private String now() { 256 if (formatter == null) { 257 formatter = DateFormat.getTimeInstance(); 258 formatter.setTimeZone(TimeZone.getDefault()); 259 } 260 return formatter.format(new Date()); 261 } 262 263 266 private void make() { 267 final String targetString = getTargetString(); 268 final String [] args = targets; 269 tasks.add(new Runnable () { 270 public void run() { 271 makeTask(args, targetString); 272 } 273 }); 274 } 275 276 280 private void loadTask() { 281 String fileName = make.getFile().getPath(); 282 try { 283 make.load(); 284 make.getOut().println("Loaded " + fileName + " at " + now()); 285 } 286 catch (FileNotFoundException ex) { 287 make.getOut().println("Cannot find makefile " + fileName); 288 } 289 catch (ParseError pe) { 290 make.getOut().println(pe.getFileName() + ":" + pe.getLineNumber() 291 + ": Parse error: " + pe.getMessage()); 292 } 293 } 294 295 298 private void load() { 299 tasks.add(new Runnable () { 300 public void run() { 301 loadTask(); 302 } 303 }); 304 } 305 306 309 private void cancel() { 310 tasks.removeAll(); 311 make.setInterruptEnabled(true); 312 make.getOut().println("Cancel requested"); 313 } 314 315 318 public static void createMakeWindow(Make make, String [] targets) { 319 loadResources(); 320 Frame f = new Frame(Make.getVersion()); 321 f.addWindowListener(new WindowAdapter() { 322 public void windowClosing(WindowEvent e) { 323 System.exit(0); 324 } 325 }); 326 f.setFont(Font.decode(getFontResource())); 327 328 Label label = new Label(makefileLabel(make)); 329 f.add(label, "North"); 330 MakeWindow mw = new MakeWindow(make, targets, 331 getRowsResource(), 332 getColumnsResource()); 333 mw.setEditable(false); 334 f.add(mw, "Center"); 335 f.setMenuBar(createMenuBar(mw, make, f, label)); 336 Panel panel = new Panel(new BorderLayout()); 337 Label targetLabel = new Label(" Targets:"); 338 MakeInput field = new MakeInput(mw.getTargetString()); 339 field.addActionListener(mw); 340 panel.add(targetLabel, "West"); 341 panel.add(field, "Center"); 342 f.add(panel, "South"); 343 label.addFocusListener(field); 344 mw.addFocusListener(field); 345 panel.addFocusListener(field); 346 targetLabel.addFocusListener(field); 347 348 f.pack(); 349 f.show(); 350 field.requestFocus(); 351 mw.load(); 352 } 353 354 private static String makefileLabel(Make make) { 355 return " Makefile: " + make.getFile().getPath(); 356 } 357 358 private static MenuBar createMenuBar(final MakeWindow mw, 359 final Make make, 360 final Frame frame, 361 final Label label) { 362 MenuBar mb = new MenuBar(); 363 Menu m = new Menu("File"); 364 mb.add(m); 365 MenuItem mi; 366 mi = new MenuItem("Reload", new MenuShortcut(KeyEvent.VK_R)); 367 mi.addActionListener(new ActionListener() { 368 public void actionPerformed(ActionEvent e) { 369 mw.load(); 370 } 371 }); 372 m.add(mi); 373 mi = new MenuItem("File load", new MenuShortcut(KeyEvent.VK_F)); 374 mi.addActionListener(makefileDialog(mw, make, frame, label)); 375 m.add(mi); 376 mi = new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_X)); 377 mi.addActionListener(new ActionListener() { 378 public void actionPerformed(ActionEvent e) { 379 System.exit(0); 380 } 381 }); 382 m.add(mi); 383 m = new Menu("Commands"); 384 mb.add(m); 385 mi = new MenuItem("Make", new MenuShortcut(KeyEvent.VK_A)); 388 mi.addActionListener(new ActionListener() { 389 public void actionPerformed(ActionEvent e) { 390 mw.make(); 391 } 392 }); 393 m.add(mi); 394 mi = new MenuItem("Cancel", new MenuShortcut(KeyEvent.VK_C)); 395 mi.addActionListener(new ActionListener() { 396 public void actionPerformed(ActionEvent e) { 397 mw.cancel(); 398 } 399 }); 400 m.add(mi); 401 mi = new MenuItem("To Clipboard", new MenuShortcut(KeyEvent.VK_T)); 402 mi.addActionListener(copyTranscriptAction(mw)); 403 m.add(mi); 404 m = new Menu("Options"); 405 mb.add(m); 406 CheckboxMenuItem cmi = new CheckboxMenuItem("Verbose", make.isVerbose()); 407 cmi.addItemListener(new ItemListener() { 408 public void itemStateChanged(ItemEvent e) { 409 make.setVerbose(e.getStateChange() == ItemEvent.SELECTED); 410 } 411 }); 412 m.add(cmi); 413 cmi = new CheckboxMenuItem("Just Print", make.isJustPrinting()); 414 cmi.addItemListener(new ItemListener() { 415 public void itemStateChanged(ItemEvent e) { 416 make.setJustPrinting(e.getStateChange() == ItemEvent.SELECTED); 417 } 418 }); 419 m.add(cmi); 420 return mb; 421 } 422 423 private static ActionListener makefileDialog(final MakeWindow mw, 424 final Make make, 425 final Frame frame, 426 final Label label) { 427 return new ActionListener() { 428 public void actionPerformed(ActionEvent e) { 429 FileDialog fd = new FileDialog(frame, "Select makefile name"); 430 fd.setFile(make.getFile().getPath()); 431 fd.show(); 432 String makefile = fd.getFile(); 433 if (makefile != null) { 434 makefile = fd.getDirectory() + makefile; 435 make.setFile(new File(makefile)); 436 label.setText(makefileLabel(make)); 437 mw.load(); 438 } 439 } 440 }; 441 } 442 443 private static ActionListener copyTranscriptAction(final MakeWindow mw) { 444 final Clipboard clipboard = mw.getToolkit().getSystemClipboard(); 445 return new ActionListener() { 446 public void actionPerformed(ActionEvent e) { 447 String srcData; 448 if (mw.getSelectionStart() < mw.getSelectionEnd()) 449 srcData = mw.getSelectedText(); 450 else { 451 mw.selectAll(); 452 srcData = mw.getText(); 453 } 454 if (srcData != null) { 455 StringSelection contents = new StringSelection(srcData); 456 clipboard.setContents(contents, mw); 457 } 458 } 459 }; 460 } 461 462 465 public void lostOwnership(Clipboard clipboard, Transferable contents) { 466 select(0, 0); } 468 469 472 473 private static ResourceBundle resources; 474 475 478 private static void loadResources() { 479 if (resources == null) { 480 try { 481 resources = ResourceBundle.getBundle(JMK_PROPERTIES); 482 } 483 catch (MissingResourceException mre) { 484 } 486 } 487 } 488 489 494 private static String getResourceString(String nm, String defaultValue) { 495 if (resources == null) 496 return defaultValue; 497 try { 498 return resources.getString(nm); 499 } 500 catch (MissingResourceException mre) { 501 return defaultValue; 502 } 503 } 504 505 511 private static int getResourceInt(String nm, int defaultValue) { 512 if (resources == null) 513 return defaultValue; 514 String str; 515 try { 516 str = resources.getString(nm); 517 } 518 catch (MissingResourceException mre) { 519 return defaultValue; 520 } 521 if (str == null) 522 return defaultValue; 523 try { 524 return Integer.parseInt(str); 525 } 526 catch (NumberFormatException ex) { 527 return defaultValue; 528 } 529 } 530 531 private static String getFontResource() { 532 return getResourceString("jmk.font", DEFAULT_FONT); 533 } 534 535 private static int getColumnsResource() { 536 return getResourceInt("jmk.columns", DEFAULT_COLUMNS); 537 } 538 539 private static int getRowsResource() { 540 return getResourceInt("jmk.rows", DEFAULT_ROWS); 541 } 542 543 548 public static void main(String [] args) { 549 try { 550 Make make = new Make(); 551 if (args.length > 0) { 552 String [] targets = new String [args.length - 1]; 553 for (int i = 0; i < targets.length; i++) 554 targets[i] = args[i + 1]; 555 make.setFile(new File(args[0])); 556 MakeWindow.createMakeWindow(make, targets); 557 } 558 else { 559 System.out.println("Usage: java " + MakeWindow.class.getName() + 560 " makefile [ target ]*"); 561 System.exit(1); 562 } 563 } 564 catch (Throwable t) { 565 System.err.println("Internal error: " + t.getMessage()); 566 t.printStackTrace(); 567 System.exit(1); 568 } 569 } 570 } 571 | Popular Tags |