import javax.swing.* ;
import java.awt.* ;
import java.awt.event.* ;
import java.util.function.DoubleUnaryOperator ;
public class Main
extends JFrame { private JComboBox< String> typeBox;
private GraphPanel graphPanel;
public Main( ) {
setTitle( "Equation Plotter" ) ;
setSize( 800 , 600 ) ;
setDefaultCloseOperation( EXIT_ON_CLOSE) ;
// --- Top Panel ---
topPanel.
add ( new JLabel ( "Equation Type:" ) ) ; typeBox
= new JComboBox
<> ( new String [ ] { "Linear" , "Quadratic" , "Trigonometric" , "Exponential" , "Custom"
} ) ;
topPanel.add ( typeBox) ;
topPanel.
add ( new JLabel ( "Equation (use x):" ) ) ; equationField
= new JTextField ( "y = 2*x + 3" ,
20 ) ; topPanel.add ( equationField) ;
topPanel.add ( plotButton) ;
// --- Graph Panel ---
graphPanel = new GraphPanel( ) ;
// --- Button Action ---
plotButton.addActionListener ( e -> {
String eq
= equationField.
getText ( ) .
replace ( "y=" ,
"" ) .
replace ( " " ,
"" ) ; graphPanel.setEquation ( parseEquation( eq) ) ;
graphPanel.repaint ( ) ;
} ) ;
}
// --- Parse equation into a function ---
private DoubleUnaryOperator parseEquation
( String eq
) { try {
if ( eq.contains ( "sin" ) ) {
return x
-> Math .
sin ( evalReplace
( eq, x
) ) ; } else if ( eq.contains ( "cos" ) ) {
return x
-> Math .
cos ( evalReplace
( eq, x
) ) ; } else if ( eq.contains ( "tan" ) ) {
return x
-> Math .
tan ( evalReplace
( eq, x
) ) ; } else {
return x -> evalReplace( eq, x) ;
}
return x -> 0 ;
}
}
// --- Evaluate expression safely ---
private double evalReplace
( String eq,
double x
) { try {
String replaced
= eq.
replace ( "x" ,
"(" + x
+ ")" ) ; return ( ( Number ) new javax.
script .
ScriptEngineManager ( ) .getEngineByName ( "JavaScript" )
.eval ( replaced) ) .doubleValue ( ) ;
return 0 ;
}
}
// --- Graph Panel Class ---
class GraphPanel
extends JPanel { private DoubleUnaryOperator function = x -> 0 ;
void setEquation( DoubleUnaryOperator func) {
this .function = func;
}
protected void paintComponent
( Graphics g
) { super .paintComponent ( g) ;
int w = getWidth( ) ;
int h = getHeight( ) ;
g2.
setColor ( Color .
WHITE ) ; g2.fillRect ( 0 , 0 , w, h) ;
g2.
setColor ( Color .
LIGHT_GRAY ) ; for ( int i = 0 ; i < w; i += 20 )
g2.drawLine ( i, 0 , i, h) ;
for ( int j = 0 ; j < h; j += 20 )
g2.drawLine ( 0 , j, w, j) ;
g2.
setColor ( Color .
BLACK ) ; g2.drawLine ( 0 , h / 2 , w, h / 2 ) ; // X-axis
g2.drawLine ( w / 2 , 0 , w / 2 , h) ; // Y-axis
double scale = 40 ; // pixels per unit
for ( int i = 1 ; i < w; i++ ) {
double x1 = ( i - w / 2.0 ) / scale;
double x2 = ( i + 1 - w / 2.0 ) / scale;
double y1 = function.applyAsDouble ( x1) ;
double y2 = function.applyAsDouble ( x2) ;
int px1 = i;
int py1 = ( int ) ( h / 2 - y1 * scale) ;
int px2 = i + 1 ;
int py2 = ( int ) ( h / 2 - y2 * scale) ;
g2.drawLine ( px1, py1, px2, py2) ;
}
}
}
public static void main
( String [ ] args
) { }
}
aW1wb3J0IGphdmF4LnN3aW5nLio7CmltcG9ydCBqYXZhLmF3dC4qOwppbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5Eb3VibGVVbmFyeU9wZXJhdG9yOwoKcHVibGljIGNsYXNzIE1haW4gZXh0ZW5kcyBKRnJhbWUgewogICAgcHJpdmF0ZSBKQ29tYm9Cb3g8U3RyaW5nPiB0eXBlQm94OwogICAgcHJpdmF0ZSBKVGV4dEZpZWxkIGVxdWF0aW9uRmllbGQ7CiAgICBwcml2YXRlIEpCdXR0b24gcGxvdEJ1dHRvbjsKICAgIHByaXZhdGUgR3JhcGhQYW5lbCBncmFwaFBhbmVsOwoKICAgIHB1YmxpYyBNYWluKCkgewogICAgICAgIHNldFRpdGxlKCJFcXVhdGlvbiBQbG90dGVyIik7CiAgICAgICAgc2V0U2l6ZSg4MDAsIDYwMCk7CiAgICAgICAgc2V0RGVmYXVsdENsb3NlT3BlcmF0aW9uKEVYSVRfT05fQ0xPU0UpOwogICAgICAgIHNldExheW91dChuZXcgQm9yZGVyTGF5b3V0KCkpOwoKICAgICAgICAvLyAtLS0gVG9wIFBhbmVsIC0tLQogICAgICAgIEpQYW5lbCB0b3BQYW5lbCA9IG5ldyBKUGFuZWwoKTsKICAgICAgICB0b3BQYW5lbC5hZGQobmV3IEpMYWJlbCgiRXF1YXRpb24gVHlwZToiKSk7CiAgICAgICAgdHlwZUJveCA9IG5ldyBKQ29tYm9Cb3g8PihuZXcgU3RyaW5nW117CiAgICAgICAgICAgICAgICAiTGluZWFyIiwgIlF1YWRyYXRpYyIsICJUcmlnb25vbWV0cmljIiwgIkV4cG9uZW50aWFsIiwgIkN1c3RvbSIKICAgICAgICB9KTsKICAgICAgICB0b3BQYW5lbC5hZGQodHlwZUJveCk7CgogICAgICAgIHRvcFBhbmVsLmFkZChuZXcgSkxhYmVsKCJFcXVhdGlvbiAodXNlIHgpOiIpKTsKICAgICAgICBlcXVhdGlvbkZpZWxkID0gbmV3IEpUZXh0RmllbGQoInkgPSAyKnggKyAzIiwgMjApOwogICAgICAgIHRvcFBhbmVsLmFkZChlcXVhdGlvbkZpZWxkKTsKCiAgICAgICAgcGxvdEJ1dHRvbiA9IG5ldyBKQnV0dG9uKCJQbG90Iik7CiAgICAgICAgdG9wUGFuZWwuYWRkKHBsb3RCdXR0b24pOwoKICAgICAgICBhZGQodG9wUGFuZWwsIEJvcmRlckxheW91dC5OT1JUSCk7CgogICAgICAgIC8vIC0tLSBHcmFwaCBQYW5lbCAtLS0KICAgICAgICBncmFwaFBhbmVsID0gbmV3IEdyYXBoUGFuZWwoKTsKICAgICAgICBhZGQoZ3JhcGhQYW5lbCwgQm9yZGVyTGF5b3V0LkNFTlRFUik7CgogICAgICAgIC8vIC0tLSBCdXR0b24gQWN0aW9uIC0tLQogICAgICAgIHBsb3RCdXR0b24uYWRkQWN0aW9uTGlzdGVuZXIoZSAtPiB7CiAgICAgICAgICAgIFN0cmluZyBlcSA9IGVxdWF0aW9uRmllbGQuZ2V0VGV4dCgpLnJlcGxhY2UoInk9IiwgIiIpLnJlcGxhY2UoIiAiLCAiIik7CiAgICAgICAgICAgIGdyYXBoUGFuZWwuc2V0RXF1YXRpb24ocGFyc2VFcXVhdGlvbihlcSkpOwogICAgICAgICAgICBncmFwaFBhbmVsLnJlcGFpbnQoKTsKICAgICAgICB9KTsKICAgIH0KCiAgICAvLyAtLS0gUGFyc2UgZXF1YXRpb24gaW50byBhIGZ1bmN0aW9uIC0tLQogICAgcHJpdmF0ZSBEb3VibGVVbmFyeU9wZXJhdG9yIHBhcnNlRXF1YXRpb24oU3RyaW5nIGVxKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKGVxLmNvbnRhaW5zKCJzaW4iKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHggLT4gTWF0aC5zaW4oZXZhbFJlcGxhY2UoZXEsIHgpKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChlcS5jb250YWlucygiY29zIikpIHsKICAgICAgICAgICAgICAgIHJldHVybiB4IC0+IE1hdGguY29zKGV2YWxSZXBsYWNlKGVxLCB4KSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXEuY29udGFpbnMoInRhbiIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4geCAtPiBNYXRoLnRhbihldmFsUmVwbGFjZShlcSwgeCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHggLT4gZXZhbFJlcGxhY2UoZXEsIHgpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgSk9wdGlvblBhbmUuc2hvd01lc3NhZ2VEaWFsb2codGhpcywgIkludmFsaWQgRXF1YXRpb24hIiwgIkVycm9yIiwgSk9wdGlvblBhbmUuRVJST1JfTUVTU0FHRSk7CiAgICAgICAgICAgIHJldHVybiB4IC0+IDA7CiAgICAgICAgfQogICAgfQoKICAgIC8vIC0tLSBFdmFsdWF0ZSBleHByZXNzaW9uIHNhZmVseSAtLS0KICAgIHByaXZhdGUgZG91YmxlIGV2YWxSZXBsYWNlKFN0cmluZyBlcSwgZG91YmxlIHgpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBTdHJpbmcgcmVwbGFjZWQgPSBlcS5yZXBsYWNlKCJ4IiwgIigiICsgeCArICIpIik7CiAgICAgICAgICAgIHJldHVybiAoKE51bWJlcikgbmV3IGphdmF4LnNjcmlwdC5TY3JpcHRFbmdpbmVNYW5hZ2VyKCkKICAgICAgICAgICAgICAgICAgICAuZ2V0RW5naW5lQnlOYW1lKCJKYXZhU2NyaXB0IikKICAgICAgICAgICAgICAgICAgICAuZXZhbChyZXBsYWNlZCkpLmRvdWJsZVZhbHVlKCk7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIC8vIC0tLSBHcmFwaCBQYW5lbCBDbGFzcyAtLS0KICAgIGNsYXNzIEdyYXBoUGFuZWwgZXh0ZW5kcyBKUGFuZWwgewogICAgICAgIHByaXZhdGUgRG91YmxlVW5hcnlPcGVyYXRvciBmdW5jdGlvbiA9IHggLT4gMDsKCiAgICAgICAgdm9pZCBzZXRFcXVhdGlvbihEb3VibGVVbmFyeU9wZXJhdG9yIGZ1bmMpIHsKICAgICAgICAgICAgdGhpcy5mdW5jdGlvbiA9IGZ1bmM7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwYWludENvbXBvbmVudChHcmFwaGljcyBnKSB7CiAgICAgICAgICAgIHN1cGVyLnBhaW50Q29tcG9uZW50KGcpOwogICAgICAgICAgICBHcmFwaGljczJEIGcyID0gKEdyYXBoaWNzMkQpIGc7CgogICAgICAgICAgICBpbnQgdyA9IGdldFdpZHRoKCk7CiAgICAgICAgICAgIGludCBoID0gZ2V0SGVpZ2h0KCk7CgogICAgICAgICAgICBnMi5zZXRDb2xvcihDb2xvci5XSElURSk7CiAgICAgICAgICAgIGcyLmZpbGxSZWN0KDAsIDAsIHcsIGgpOwoKICAgICAgICAgICAgZzIuc2V0Q29sb3IoQ29sb3IuTElHSFRfR1JBWSk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdzsgaSArPSAyMCkKICAgICAgICAgICAgICAgIGcyLmRyYXdMaW5lKGksIDAsIGksIGgpOwogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGg7IGogKz0gMjApCiAgICAgICAgICAgICAgICBnMi5kcmF3TGluZSgwLCBqLCB3LCBqKTsKCiAgICAgICAgICAgIGcyLnNldENvbG9yKENvbG9yLkJMQUNLKTsKICAgICAgICAgICAgZzIuc2V0U3Ryb2tlKG5ldyBCYXNpY1N0cm9rZSgyKSk7CiAgICAgICAgICAgIGcyLmRyYXdMaW5lKDAsIGggLyAyLCB3LCBoIC8gMik7IC8vIFgtYXhpcwogICAgICAgICAgICBnMi5kcmF3TGluZSh3IC8gMiwgMCwgdyAvIDIsIGgpOyAvLyBZLWF4aXMKCiAgICAgICAgICAgIGcyLnNldENvbG9yKENvbG9yLlJFRCk7CiAgICAgICAgICAgIGRvdWJsZSBzY2FsZSA9IDQwOyAvLyBwaXhlbHMgcGVyIHVuaXQKCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgdzsgaSsrKSB7CiAgICAgICAgICAgICAgICBkb3VibGUgeDEgPSAoaSAtIHcgLyAyLjApIC8gc2NhbGU7CiAgICAgICAgICAgICAgICBkb3VibGUgeDIgPSAoaSArIDEgLSB3IC8gMi4wKSAvIHNjYWxlOwogICAgICAgICAgICAgICAgZG91YmxlIHkxID0gZnVuY3Rpb24uYXBwbHlBc0RvdWJsZSh4MSk7CiAgICAgICAgICAgICAgICBkb3VibGUgeTIgPSBmdW5jdGlvbi5hcHBseUFzRG91YmxlKHgyKTsKCiAgICAgICAgICAgICAgICBpbnQgcHgxID0gaTsKICAgICAgICAgICAgICAgIGludCBweTEgPSAoaW50KSAoaCAvIDIgLSB5MSAqIHNjYWxlKTsKICAgICAgICAgICAgICAgIGludCBweDIgPSBpICsgMTsKICAgICAgICAgICAgICAgIGludCBweTIgPSAoaW50KSAoaCAvIDIgLSB5MiAqIHNjYWxlKTsKCiAgICAgICAgICAgICAgICBnMi5kcmF3TGluZShweDEsIHB5MSwgcHgyLCBweTIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBTd2luZ1V0aWxpdGllcy5pbnZva2VMYXRlcigoKSAtPiBuZXcgTWFpbigpLnNldFZpc2libGUodHJ1ZSkpOwogICAgfQp9